관리 메뉴

사과하는 제라스

8. 응용 개발 본문

대학 전공 공부/데이터베이스1

8. 응용 개발

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
    반응형

    '대학 전공 공부 > 데이터베이스1' 카테고리의 다른 글

    7. 오라클 실습 2  (0) 2022.06.14
    6. 데이터베이스 시스템 주요 기능  (0) 2022.06.13
    5. SQL 2  (0) 2022.04.25
    SQL Examples  (0) 2022.04.25
    3. SQL 1 - DML  (0) 2022.04.25