[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는
static
db 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 <-
SQLBindCol
10.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;
댓글남기기