[Database] 9.DB programming
        
        
      REF: fundamentals of database systems 7th edition
Overview
Approaches
1. ⭐️Embedded commands
- db statement들이 host programming language에 Embedded되어있음.
- SQL이 대표적인 예시이며, ⭐️EXEC SQL같은 특수 접두사로 구분된다.
- ⭐️precompiler, preproccessor가 이를 보고 분리컴파일을한다.
2. Library of database functions
- host programming language 내에서 database를 직접 호출할 수 있다.
- ⭐️API(Application Programming Interface): 응용프로그램에서 DB를 직접 접속한다.- SQL/CLI, ODBC등이 있다.
 
- OOPLs(객체지향언어)에서는 클래스 라이브러리가 사용된다.
3. Designing a brand-new language
- DB 프로그래밍언어는 처음부터 DB모델과 질의어와 호환되도록 만들어졌다.
- 반복문, 조건문 등이 DB 언어에 추가되어 완전한 프로그래밍 언어로 변환된다.
- Impedance mismatch라고 불리는 DB model과 프로그래밍 언어와의 차이로부터 나오는 문제를 줄인다.
Sequence
architecture
- top-tier : client program -> Web client, mobile app
- middle-tier : application program -> business software application의 logic구현, 백엔드 서버
- bottom-tier : database servers -> data를 실제로 접근, 업데이트
Sequence
- application program(백엔드 서버)이 DB server와 connection을 시작.- connection
        CONNECT TO <server-name> AS <connection-name> AUTHORIZATION <user-account-info>;
- connection change
        SET CONNECTION <connection-name>;
 
- connection
        
- application 프로그램이 DB server에 쿼리를 보내 db를 업데이트
- DB access가 더이상 필요하지 않을때, program은 connection을 종료
    - Disconnection
        DISCONNECT <connection-name>;
 
- Disconnection
        
Embedded SQL
- 대부분의 SQL Statement들은 범용목적 host programming language에 embedded될 수 있다.
Usage
- EXEC SQL을 통해- ⭐️preprocessor(precompiler)가 SQL statements와 host language를 구분한다.
- END-EXEC,- semicolon을 통해 statement를 끝맺는다.
- SQLCODE/SQLSTATE- program과 SQL간 통신
- ⭐️0 || 00000-> SQL이 성공적으로 실행되었다.
- other values -> 실패
- SQLSTATE는 이후 버전에 추가되어- 00000으로 에러를 표현한다.(ex, 02000 : no more data)
 
- Shared Variables- C program과 embedded SQL statements와 동시에 사용될 수 있음.
- SQL statement내에서 host변수와 구분하기위해 :(colon)으로 구분.
 
single tuple 예시
loop = 1;
while(loop)
{
	prompt("Enter a SSN", ssn);
	EXEC SQL //SQL 시작
		select FNAME, MINIT, LNAME, ADDRESS, SALARY
		into :fname, :minit, :lname, :address, :salary //shared variable선언
		from EMPLOYEE where SSN = :ssn;
	if (SQLCODE == 0)
		printf(fname, minit, lname, address, salary);
	else
		printf("no ssn : %d", ssn);
	prompt("need more ? 1 for yes, 0 for no", loop);
}
- 단일 tuple만을 결과로 받을 수 있다.
- ssn을 사용자로부터 입력받는다.
- INTO 절로 shared variable에 값을 받는다.
- SQLCODE가 0일때 정상실행된것이므로, 결과값이 출력된다.
multiple tuple 예시
⭐️CURSOR
- embedded SQL에서는 CURSOR를 통해 multiple tuple을 가져올 수 있다.
- query의 결과로 반환된 tuple 집합에서 1개의 tuple을 가리키는 변수
- DECLARE를 통해 CURSOR 변수를 선언.
- OPEN CURSOR를 통해- 결과 쿼리의 ⭐️첫 번째 줄 이전의 줄에 위치시킨다.
- CLOSE CURSOR로 결과 쿼리를 더이상 사용하지 않는다고 알린다.
- FETCH로 현재 결과를 변수에 복사하고, CURSOR를 다음 줄로 옮긴다.
prompt("enter a dname", dname);
EXEC SQL
	SELECT Dnumber INTO :dnumber
	FROM DEPARTMENT WHERE Dname = :dname;
EXEC SQL DECLARE EMP CURSOR FOR //Cursor Declare
	SELECT Ssn, Fname, Minit, Lname, Salary
	FROM EMPLOYEE WHERE Dno = :dnumber
	FOR UPDATE OF Salary;
EXEC SQL OPEN EMP;//Cursor Open, before first line
EXEC SQL FETCH FROM EMP INTO :ssn, :fname, :minit, :lname, :salary;//Fetch into first line
while (SQLCODE == 0)
{
	printf("Emp name is", Fname, Minit, Lname);
	prompt("Enter raise", raise);
	EXEC SQL
		UPDATE EMPLOYEE
		SET Salary = Salary + raise
		WHERE CURRENT OF EMP;
	EXEC SQL FETCH FROM EMP INTO :ssn, :fname, :minit, :lname, :salary;//Fetch into next line
}
EXEC SQL CLOSE EMP;//end line
SQLJ
- SQLJ는 JAVA에서의 Embedded SQL command이다.
- SQLJ translator가 SQL 구문을 Java로 변환해준다.
- java.sql의 특정 클래스를 사용한다.
- Retrieving Multiple Tuples in SQLJ
    - SQLJ는 CURSOR같은 iterator를 2개 지원한다.
        - ⭐️named iterator- query result 내에서 속성의- 이름과 타입까지 받아온다.
- ⭐️positional iterator- 속성의- 타입만 받아온다.
 
- ⭐️FETCH: query result로부터 다음 tuple로 이동.- FETCH <iterator-variable> INTO <program-variables>
 
 
- SQLJ는 CURSOR같은 iterator를 2개 지원한다.
        
Dynamic SQL
정의
- embedded는 staticdb programming approach이다.(SQL 구절이 한번 작성되면 다시 프로그램 컴파일전까지는 바뀌지 않는다는 것 때문에.)
- Dynamic SQL은 runtime에 쿼리를 정의한다.- 프로그램을 실행하면 실행도중에 쿼리를 사용자로부터 입력받는다.
 
- API function call은- dynamic approach에 가깝다.
- 단점
    - runtime에 문법오류를 확인해야한다.
- 이전에 type과 속성수를 알고있지 않다면 프로그래밍이 어려워진다.
 
examples
- ⭐️PREPARE: 사용자로부터 입력받은 문자열을 query로 변환, 컴파일한다.
- ⭐️EXECUTE: 변환한 query를 실행한다.
- ⭐️EXECUTE IMMEDIATE:- PREPARE+- EXECUTE
EXEC SQL BEGIN DECLARE SECTION;
varchar sqlupdatestring [256];
EXEC SQL END DECLARE SECTION;
...
prompt("Enter the Update Command: ", sqlupdatestring); //runtime에 사용자로부터 쿼리를 입력받는다.
EXEC SQL PREPARE sqlcommand FROM :sqlupdatestring; //query compiler가 쿼리를 컴파일한다.
EXEC SQL EXECUTE sqlcommand; //실행
ODBC
정의
- ODBC(open database connectivity)는 DB에 접근하는 공개 표준 API이다.
- ⭐️프로그래밍 언어 상에서, 서로 다른 종류의 DB에 접근할 수 있게 해준다.
구조
 

- Application : ODBC function을 호출한다.
- ⭐️Driver Manager:- Load and unload drivers
- ODBC function call을 처리하거나, Driver에 넘긴다.
 
- ⭐️Driver:- ODBC function call을 처리
- SQL request를 data source에 넘긴다.
- 결과를 AP에게 되돌린다.
 
- ⭐️Data source :
    - user가 access하고자 하는 data와 data 관련 OS, DBMS, network platform으로 구성된다.
 
Handle
- ODBC가 지원해준다.
- handle자체는 특정 item을 식별하기 위한 값이다.
- 4가지 type의 handle이 있다.
    - Environment handle- 유효 연결 핸들이나,- 현재 가동 중인 연결 핸들 등 광역 정보를 위한 기억장소를 식별한다.
- ODBC를 사용하는 환경에 대한 정보를 저장
 
- Connection handle- 특정 연결에 관한 정보를 위한 기억장소 식별한다.
 
- Statement handle- SQL문에 관한 정보를 위한 기억장소 식별
 
- Descriptor handle- SQL statement에 대한 여러 정보를 위한 기억장소 식별
- SQL문의 길이, 주소 등에 대한 정보와 데이터 유형, null-terminated인지여부 등에 대한 정보를 저장한다.
- 자동, 명시적할당.
 
 
수행단계
- 아래 절차를 ODBC가 알아서 해준다.

- SQLAllocENV : Environment handle메모리 할당
- SQLAllocConnect : Connection handle메모리 할당
- SQLConnect : Driver 로드, data source와 연결
- SQLAllocStmt : Statement handle메모리 할당
- Process SQL Stmt : SQL statement 처리
- Receive Result : 결과를 받아옴 ——–4의 역순
- SQLFreeStmt : Stmt 메모리 해제
- SQLDisconnect : data source와 연결 해제
- SQLFreeConnect : Connection handle 메모리 해제
- SQLFreeEnv : Environment handle 메모리 해제
JDBC
- 
    ODBC중, JAVA를 사용할때를 의미한다. 
- JDBC Driver
    - 특정 Vendor가 제공하는 RDBMS에 대해 JDBC에 지정된 클래스, 관련 객체, 함수를 구현한 것.
- 프로그램이 JDBC driver가 있는 모든 RDBMS에 접근 가능하게끔 한다.
 
- CLI와 구문적으로 차이가 있음(non-semantic)
 
SQL/CLi
- 1990년대 말, 표준화된 방법.
- API function call을 사용하는 방법 중 하나이다.
- ODBC처럼 같은 프로그램 내에서 여러 DB에 접속할 수 있게해준다.
- sqlcli.h같이 특정 라이브러리가 설치되어야한다.
- 호출 시, SQL statement는
    - 사용자에게 특정 값을 입력받는다.
- 컴파일 타임에 SQLPrepare이 프로그램에 static하게 입력된 query를 컴파일해 static binding해놓는다.
- 사용자가 특정 값을 입력하면 이 값이 SQLBindParameter를 통해 이 쿼리와 binding된다.
 
Components
- 
    ODBC의 일반화 
- Environment record(SQLHENV):- 1개 이상의 DB connection 추적에 사용되며,- 환경정보를 세팅한다.- 앞서봤듯, SQL/CLI를 사용하는 환경에대한 변수를 설정하는 것이다.
 
- Connection record(SQLHDBC):- 특정 DB 연결에 필요한 정보추적- 특정 DB와 연결했을때 이 연결을 식별한다.
 
- Statement record(SQLHSTMT): 1개 SQL 구문에 필요한 정보 추적
- Description record(SQLHDEC): tuple 추적
Steps
- SQLAllocHandle이 embedded SQL 에서의 SQLAllocENV, SQLAllocConnect, SQLAllocStmt를 처리한다.
- load SQL/CLI library
- record handle variable 선언 (SQLHENV, SQLHDBC, SQLHSTMT, SQLHDEC)
- set environment record<-SQLAllocHandle
- set connection record<-SQLAllocHandle
- set statement record<-SQLAllocHandle
- statement 준비 <- SQLPrepare
- program variable에 parameter 바인딩 <- SQLBindParameter
- SQL statement execute <- SQLExecute
- Bound columns in a query to C variable <- SQLBindCol10.1줄씩 column value를 C variable로 받아옴 <-SQlFetch
example code
#include "sqlcli.h"
void printsal()
{
	SQLHENV		env1; //여러개의 DB 연결 위한 pointer
	SQLHDBC		con1; //1개 DB 연결 식별 pointer
	SQLHSTMT	stmt1; //statement pointer
	SQLRETURN ret1, ret2, ret3, ret4;
	//set environment record -> 1개이상의 DB 연결 관리 및 환경 설정
	ret1 = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env1);
	//set connection record -> 특정 DB와의 연결 추적
	if (!ret1)
		ret2 = SQLAllocHandle(SQL_HANDLE_DBC, env1, &con1);
	else
		exit(1);
	//연결
	if (!ret2)//dbserver 이름, 계정이름, 비밀번호
		ret3 = SQLConnect(con1, "dbs", SQL_NTS, "js", SQL_NTS, "xyz");
	else
		exit(1);
	//set statement record
	if (!ret3)
		ret4 = SQLAllocHandle(SQL_HANDLE_STMT, con1, &stmt1);
	else
		exit(1);
	//SQLPREPARE -> query를 컴파일하고, static binding해서 stmt1에 할당한다.
	SLQPrepare(stmt1, "SELECT Lname, Salary FROM EMPLOYEE WHERE Ssn = ?", SQL_NTS);
	prompt("Enter Ssn", ssn);
	//SQLBindParameter -> query의 n번째 parameter(?)에 특정 값을 binding한다.
	SQLBindParameter(stmt1, 1, SQL_CHAR, &ssn, 9, &fetchlen1);
	//SQLExecute -> EXECUTE한 결과를 stmt1에 저장.
	ret1 = SQLExecute(stmt1);
	if (!ret1)
	{
		//SQLBindCol -> stmt1의 Column값을 각 lname, salary라는 C변수에 바인딩한다.
		SQLBindCol(stmt1, 1, SQL_CHAR, &lname, 15, &fetchlen1);
		SQLBindCol(stmt1, 2, SQL_FLOAT, &salary, 4, &fetchlen2);
		//SQLFetch -> 다음 줄로 이동
		ret2 = SQLFetch(stmt1);
		if (!ret2)
			printf(ssn, lanme, salary);
		else
			printf("SSN NOT EXITS");
	}
}
- pointers
    
- 각 함수별 원형은 MS ODBC DOCS에서 참고
Database Stored Procedures
three-tier architecture

- presentation tier : 사용자 인터페이스, GUI만 처리한다. 흔히 말하는 프론트엔드가 여기에 속한다.
- application tier : 비즈니스 로직을 수행한다. 요청되는 정보를 가공하고 처리한다. 벡엔드라고도 불리며, middleware라고도 불린다.
- data tier : DB, DBMS에 접근해 데이터를 관리하는 것을 의미. 백엔드를 말할때, 이를 포함하기도 한다.
정의
- 사람들이 흔히 말하는 백엔드는 웹서버 + DB를 포함하지만, 보통 웹서버와 DB server가 돌아가는 머신은 다르다.
- 그래서 가끔은, DB를 직접 가공하고 처리하는 함수나 procedure을 웹서버가 아닌DB server에 저장하는게 유용하다.
- 이렇게 저장된 db program module을 stored procedures라고 부른다.
- SQL 표준에서는 이렇게 DB server측에 저장된 db program module을 persistent stored module이라고 부른다.
장점
- db program이 복수의 application에 필요하다면, db server측에 저장될 수 있으며, db server에 연결된 모든 application program들이 사용할 수 있다.
- db program은 1개의 application만 사용하진 않는다.
    - ⭐️modularity가 높아지고, ⭐️duplication이 낮아진다.
 
- ⭐️데이터 전송시간과 통신비용이 감소한다.- db server와 application program(web server)간의 요청이 간단하게 처리될 수 있기때문.
 
- ⭐️view가 제공하는 modeling 장점을 강화- stored procedures를 통해 db 사용자들이 복잡한 derived data를 만들어지게 할 수 있다.
 
- stored procedures를 통해 db 사용자들이 
사용법
- stored procedure
    CREATE PROCEDURE <procedure name> (<parameters>) <local declarations> <procedure body>;
- stored function
    CREATE FUNCTION <function name> (<parameters>) RETURNS <return type> <local declarations> <function body>;
- call persistent stored module
    CALL <function or procedure name> (<arguments>)
SQL/PSM
- SQL standard의 일부로, psm(persistent stored modules)를 작성하는 법을 정의한다.
- 
    위에서 정의한 PSM에 더해 ⭐️loop, branching, 즉조건문과 분기문을 작성할 수 있게한다.
- 조건문
    IF <condition> THEN <statement list> ELSEIF <condition> THEN <statement list> ELSEIF <condition> THEN <statement list> ... ELSE <statement list> END IF;- shell의 조건문과 비슷하게 생겼다.
 
- 반복문
    WHILE <condition> DO <statement list> END WHILE; REPEAT <statement list> UNTIL <condition> END REPEAT;
 
      
댓글남기기