Xerath(제라스) 2022. 5. 16. 06:55
728x90
반응형

1. Embedded(내장) SQL

 

- DBS를 접근하는 방식은 주로 프로그램 내에서 접근하는 형식이 널리 쓰임.

즉, DB Application에서 DBMS에 접근함.

1) Static approach : SQL 언어가 내장됨, 즉, SQL 언어를 직접 프로그램에서 씀.

ex) ESQL/C, ESQL/C++, SQLI 등

 

2) Dynamic approach : SQL API를 써서 씀

ex) SQL CLI, ODBC, JDBC 등

 

- 호스트 언어 : 내장 SQL 프로그램을 정의하고 있는 프로그래밍 언어 ex) C, C++, Java,...

-> 호스트 언어는 전처리 과정(pre-processing)을 통해서 내장 SQL 프로그램을 호스트언어에 삽입됨.

-> ex) C언어 내에 SQL 프로그램이 담긴 XXXX.ec 파일을 pre-processing 과정을 거치면 XXXX.c파일로 변환이 된다.

즉, pre-processing은 Embedded SQL을 API call로 바꿈.

 

- Embedded SQL에 대한 Syntax는 다양함.

1) EXEC SQL <embedded SQL 문>

2)  EXEC SQL <embedded SQL 문> END_EXEC

3) #SQL {...};

<사용예시>

ex1) EXEC SQL CONNECT ...; (DB에 connect하는 예)

 

ex2)

EXEC SQL BEGIN DECLARE SECTION

...(이곳에 variable을 정의할 수 있음.)

EXEC SQL END DECLARE SECTION;

 

ex3) EXEC SQL statement; (SQL 문장을 수행)

 

- Application program에서 cursor 개념이 중요함.

두 언어 간의 자료 처리 방식의 차이로 인한 불일치(=impedence mismatch)로 인해 생김.

ex) multiset은 SQL은 있지만 호스트 언어에는 거의 없는 개념임. 일부는 지원하는데 모든 데이터가 메모리 위에 올라온다는 가정 하에만 지원함.

 

이를 해결하는 방법 : cursor

cursor를 통해서 SQL 문장의 결과치를 호스트 언어에서 하나씩 받아올 수 있음.

 

- cursor의 순서 4가지

1) declare

EXEC SQL declare myCursor cursor for
	select sID, name from student where totalCredit > :creditAmount;

2) open

EXEC SQL open myCursor;

3) fetch

EXEC SQL fetch myCursor into :si, :sn; //tuple by tuple로 값이 넘어옴. sID->si, name->sn
//si, sn은 지역변수인데 미리 앞에서 variable에 대한 정의가 되어있어야 함.

fetch 해올 때마다 SQLCA영역의 SQLSTATE 변수에 실행 성공 여부가 저장됨.

00000 : 성공, 02000 : 더이상의 터플이 없음 을 의미함.

 

4) close

EXEC SQL close myCursor;

 

<cursor 사용예시>

#include <stdio.h> //C로 짠 코드임.
EXEC SQL define FNAME_LEN 15; //define 한 부분.
EXEC SQL define LNAME_LEN 15;
main(){
    EXEC SQL BEGIN DECLARE SECTION;
        char fname[ FNAME_LEN + 1 ]; //길이를 증가 시킴
        char lname[ LNAME_LEN + 1 ];
    EXEC SQL END DECLARE SECTION;
    EXEC SQL connect to 'myServer';

    EXEC SQL declare demoCursor cursor for
        select firstName, lastName
        from customer
        where :deptName < 'C';
    EXEC SQL open demoCursor;
    for(;;){ //fname, lname에 값을 받아오고 00000과 비교 후 같다면 계속 진행, 다르면 break 
            EXEC SQL fetch demoCursor into :fname, :lname;
            if(strncmp(SQLSTATE, "00000", 5) != 0) break;
            printf("%s %s\n", fname, lname);
            }
    if(strncmp(SQLSTATE, "02", 2) != 0) //SQLSTATE가 앞 2자리가 02(02000)이 아니면 print문 실행, 이 문장은 실행되지 않아야 정상.
        printf("SQLSTATE after fetch is %s\n", SQLSTATE);
    EXEC SQL close demoCursor;
    EXEC SQL disconnect current;
}

- placeholder란?

char SQLSTATE[6];
EXEC SQL BEGIN DECLARE section
	char c_eName[20];
    short c_minRating;
    float c_Age;
EXEC SQL END DECLARE section;
c_minRating = random();
EXEC SQL declare eInfo cursor for
	Select eName, age
    from myEmployee
    where rating > :c_minRating //이때 c_minRating 같은 걸 placeholder라고 하는데 동일한 문장을 변수 값을 변화시키면서 반복적으로 수행할 때 편리성을 제공함.
    order by eName;
EXEC SQL Open eInfo;
do{
	EXEC SQL fetch eInfo into :c_eName, :c_age;
    printf("%s is %d years old\n", c_eName, c_age);
} while (SQLSTATE != '02000');
EXEC SQL close eInfo;

- cursor의 update

Declare myCursorUpdate cursor for
	select *
	from professor
    where deptName = 'CS'
for update; //이렇게 작성을 해주면 추후에 업데이트를 원할 때 업데이트가 가능함.

Update professor //이렇게 해서 업데이트를 진행하면 바뀜.
set salary = salary + 100
where current of myCursorUpdate;

- Dynamic SQL : 런타임 때 생성되는 SQL

 

- Dynamic SQL의 3단계

1) prepare(런타임 때 함.)

2) compile

3) execute

 

<Dynamic SQL 사용 예시>

stcopy("select name from professor where salary > ?", myText); //Dynamic SQL은 이런식으로 씀
EXEC SQL prepare my1 from :myText;
mySalary = 1000;
EXEC SQL execute my1 using :mySalary;

//위 과정의 prepare 과정, execute 과정을 일괄적으로 수행함. 하지만 placeholder를 가질 수 없음.
stcopy("select name from professor where pID='234',
myText2");
EXEC SQL execute immediate from myText2;

 

2. ODBC, JDBC

: DBMS에 연결하여 SQL 명령문을 보낼 수 있고, 터플들을 fetch해올 수 있는 API.

 

- ODBC(Open DataBase Connectivity standard) (C, C++, C#, Visual Basic)

-> 라이브러리 형태로 지원되고 client 프로그램이 컴파일 시 링크해서 사용하면 됨.

 

- ODBC 2.0 connect

1) SQL environment 할당

2) database connection handle 할당

3) database connection open

int ODBCexample() {
RETCODE error; //리턴코드
HENV env;
HDBC conn;
SQLAllocEnv(&env); //environment allocate
SQLAllocConnect(env, &conn); //connect하는 부분 allocate
SQLConnect(conn, "db.ssu.ac.kr", SQL_NTS, "myUserID", SQL_NTS,
"myPassword", SQL_NTS); //서버에 연결하는 작업

//추가적인 work;

SQLDisconnect(conn); //끝날 때 작업들
SQLFreeConnect(conn);
SQLFreeEnv(env);
}

 

- ODBC 3.0 connect -> 2.0과 거의 비슷 connect handle 부분이 한번 더 있는 것 외엔 거의 동일함.

 

- ODBC 데이터 접근 방식 -> 동적임

1) SQLExecDirect() : SQL 문장을 수행.

2) SQLBindCol() : 결과 속성 값을 로컬 변수와 연결.

3) SQLFetch() : 터플 단위로 데이터를 받아옴.

 

char deptName[80];
float salary;
int lenOut1, lenOut2;
HSTMT stmt;
char * sqlquery = //sql 문장을 char타입으로 선언.
    "select deptName, sum(salary)
    from professor
    group by deptName";
SQLAllocStmt(conn, &stmt); //statement를 allocate.

error = SQLExecDirect(stmt, sqlquery, SQL_NTS); //그 stmt를 가지고 sqlquery를 ExecDirect하면 dynamic Sql이 수행됨.
if(error == SQLSUCCESS) {
    SQLBindCol(stmt, 1, SQL_C_CHAR, deptName, 80, &lenOut1); //sqlquery의 1번째 원소(deptName)를 deptName에 바인딩.
    SQLBindCol(stmt, 2, SQL_C_FLOAT, &salary, 0, &lentOut2); //sqlquery의 2번째 원소(sum(salary))를 salary에 바인딩.
    while(SQLFetch(stmmt) == SQL_SUCCESS){ //fetch로 값 할당.
    	printf("%s %g\n", deptName, salary);
    }
}
SQLFreeStmt(stmt, SQL_DROP);

- ODBC Dynamic SQL

ODBC는 Dynamic SQL을 지원 -> prepare(사실상 compile 작업)하는 작업이 필요함.

∴ placeholder 가질 수 있음. -> 한번 prepare된 것을 다른 값으로 여러 번 수행이 가능함.

 

SQLPrepare() : statement를 prepare하는 함수.

SQLBindParameter(), SQLNumResultCols(), SQLDescribeCol(), SQLColAttribute(),...

: DBMS에서 나오는 결과치를 로컬 value에 바인딩하는 함수.

SQLExecute() : statement를 실행하는 함수.

SQLExecDirect() : prepare와 execute을 한번에 하는 함수.

 

- SQL injection : DBMS의 데이터 보호기능을 공격하는 방식 중 하나임. -> prepare기능으로 SQL문장을 미리 컴파일하여 일부 공격 회피 가능.(∵ 데이터 타입 및 유효성 검사가 가능해지므로)

 

- ODBC metatdata

...

- ODBC Transaction

...

- ODBC comformance levels

1) Core

2) Level 1

3) Level 2

 

- JDBC (Java) : Java에서 DB 서버를 연결하게 해주는 API

...

생략

 

<정리>

 

- Database Application을 만들 때 방식이 두개 : Static vs Dynamic

Static : Embedded SQL, SQLJ

Dynamic: Database API(JDBC, ODBC 등)

API가 좀 더 사용성 측면에서 유연하고 강하고 단단하지만 느림.(하지만 최근 추세는 API를 많이 씀.)

 

3. Application Architecture

 

- 응용 프로그램은 DB와 사용자 사이의 중간자 역할이다.

 

- Application 구조의 진화

1. Mainframe 시대 -> 2. Client/Server 시대 -> 3. Web 시대

- Client-Server 응용 배치

1) Two-tier Architecture : Application이 PC에 있음.

2)Three-tier Architecture : Application이 둘로 나뉘어 client는 user interface 담당, server는 DB와 연결해서 사용하고 business logic이 존재함.

- Web : Hypertext를 기반으로 한 분산된 정보 시스템

HTML, HTTP, URL 

 

- CGI(Common Gateway Interface) : 웹 서버가 Application 서버와 연결할 때 쓰는 표준 인터페이스.

 

- state-less connection임. 대신 쿠키를 사용함.

 

- cookie : txt 파일로 된 것으로 서버에 request할 때 함께 보내짐.

728x90
반응형