一、交互式SQL的局限 & 嵌入式SQL的必要性
專業人員(如DBA)可以熟練地運用交互式SQL語言,但普通用戶卻不是那么容易上手,所以需要通過數據庫應用程序來使用數據庫。編寫一個可以與數據庫交互的數據庫應用程序,僅僅靠交互式SQL語言是無法完成的,還需要高級語言的加持。為了能讓SQL語句能和高級語言交互,我們提出了嵌入式SQL語言這一概念。
從SQL語句本身的角度來看,交互式SQL語言存在以下局限性:特別復雜的檢索結果難以用一條交互式SQL語句完成。此時需要結合高級語言中的流程控制語句(即聯合多條SQL語句)來幫助處理,這也是嵌入式SQL語言所具備的一個特性。
二、嵌入式SQL語言的形式(假設宿主語言為C語言)
1. 示例:交互式SQL語句 & 嵌入式SQL語句
- select Sname, Sage from Student where Sname = '張三';
- exec sql select Sname, Sage into :vSname, :vSage from Student where Sname = '張三';
①exec sql:引導詞,使得C編譯器知道該條語句是嵌入式SQL語句
②增加into子句:指出用於接收SQL語句檢索結果的程序變量
③為了區分屬性和程序變量,應在程序變量前加上冒號
2. 嵌入式SQL語言中變量的聲明與使用
①在嵌入式SQL語句中可以出現宿主語言中所用的變量:
- exec sql select Sname, Sage into :vSname, :vSage from Student where Sname = :specName;
②這些變量的聲明方式:
exec sql begin declare section;
char vSname[10], specName[10] = "張三";
int vSage;
exec sql end declare section;
- 注意1:宿主語言的字符串變量需多存儲'\0'
- 注意2:宿主語言的變量類型與數據庫的字段類型之間是有差異的,有些DBMS可支持自動轉換,有些則不能
三、連接/斷開數據庫
1. 在嵌入式SQL程序執行之前,首先要與數據庫進行連接
①SQL標准中建議的連接數據庫語法形式:
- exec sql connect to target-server as connect-name user user-name;
- 或exec sql connect to default;
②不同的DBMS擁有不同的連接語法形式:
- Oracle:exec sql connect :user_name identified by :user_pwd;
- DB2:exec sql connect to mydb user :user_name using :user_pwd;
2. 在嵌入式SQL程序執行之后,需要與數據庫斷開連接
①SQL標准中建議的斷開數據庫語法形式:
- exec sql disconnect conect-name;
- 或exec sql disconnect current;
②不同的DBMS擁有不同的斷開語法形式:
- Oracle:exec sql commit release;
- DB2:exec sql connect reset;
四、SQL語句執行的提交/撤消
必須通過提交或撤消來確認此次SQL語句的執行是否有效
1. SQL執行的提交:exec sql commit work;
2. SQL執行的撤消:exec sql rollback work;
3. 在斷開數據庫之前確保是否提交/撤消
①為了確保在斷開數據庫之前使用戶確認提交或撤消先前的工作,許多DBMS都設計了將提交/撤消與斷開連接捆綁在一起的語句
- Oracle:exec sql commit release;
- Oracle:exec sql rollback release;
五、事務
1. 事務的概念
①什么是事務?
- 從程序員角度看,事務是一個訪問或修改數據庫內容的程序的一次執行。也就是說,一條或多條SQL語句的一次執行被看作一個事務。
- 從DBMS角度看,事務是DBMS提供的控制數據庫操作的一種手段,通過這一手段,應用程序員將一系列的數據庫操作組合在一起作為一個整體進行操作和控制,以便DBMS能夠提供一致性狀態轉換的保證。
②事務一般是由應用程序員提出,因此它有開始和結束,事務結束前需要提交或撤消:
[Begin Transaction]
exec sql ...
exec sql ...
...
exec sql ...
exec sql commit work | exec sql rollback work
[End Transaction]
③在嵌入式SQL程序中,任何一條exec sql語句都將啟動一個新事務,只要該程序當前沒有正在處理的事務。而事務的結束總是需要應用程序員通過commit或rollback確認,即可以用commit或rollback語句結束一個事務,因此Begin Transaction和End Transaction語句是不需要的。
2. 事務的特性(ACID)
- 原子性Atomicity:DBMS能夠保證事務的一組更新操作是原子不可分的,即對DB而言,要么全做,要么全不做
- 一致性Consistency:DBMS保證事務的操作狀態是正確的,符合一致性的操作規則,它是進一步由隔離性來保證的
- 隔離性Isolation:DBMS保證並發執行的多個事務之間互相不受影響
- 持久性Durability:DBMS保證已提交事務的影響是持久的,被撤消事務的影響是可恢復的
六、游標(讀取多行數據)
1. 游標的概念
①游標是一個指向某檢索記錄集的指針
②作用:通過該指針的移動,可依次處理記錄集中的每一個記錄
2. 讀取一行數據是通過使用fetch...into語句實現的
①首次fetch時,游標是指向記錄集的第一條記錄,每一次fetch,都是先向下移動游標,然后再讀取
②記錄集有結束標識EOF,用來標記后面已沒有記錄了(即已讀完了)
3. 游標的使用
①需要先定義一個游標,再打開(執行),然后開始逐行處理,最后關閉:
exec sql declare cur_student cursor for select Sno, Sname, Sclass from Student where Sclass = '035101';
exec sql open cur_student;
exec sql fetch cur_student into :vSno, :vSname, :vSclass;
...
exec sql close cur_student;
②游標可以定義一次,多次打開(執行),多次關閉。
③標准的游標始終是自開始向結束方向移動的,每fetch一次,向結束方向移動一次,這樣一條記錄只能被訪問一次,再次訪問該記錄只能關閉該游標后重新打開。
4. 可滾動游標
①可滾動游標不同於標准的游標,它可在記錄集之間靈活移動,從而可使每條記錄被反復訪問
②定義方式:exec sql declare 游標名 [INSENSITIVE] [SCROLL] cursor for ...
③使用方式:exec sql fecth [NEXT | PRIOR | FIRST | LAST | [ABSOLUTE | RELATIVE] value_spec] from 游標名 into ...
- NEXT:向結束方向移動一條
- PRIOR:向開始方向移動一條
- FIRST:移動到第一條
- LAST:移動到最后一條
- ABSOLUTE value_spec:定向檢索指定位置的行,value_spec取值范圍為1~當前記錄集最大值
- RELATIVE value_spec:相對當前記錄向前或向后移動
- value_spec:為正數則向結束方向移動,為負數則向開始方向移動
④可滾動游標在移動前需判斷是否到結束位置EOF,或到開始位置BOF
七、數據庫記錄的增刪改
1. 刪除記錄
①查找刪除:exec sql delete from 表名 [corr_name] where 檢索條件;
②定位刪除:exec sql delete from 表名 [corr_name] where current of 游標名;
2. 更新記錄
①查找更新:exec sql update 表名 [corr_name] SET 列名 = 值 [, 列名 = 值 ... ] [where 檢索條件];
②定位更新:exec sql update 表名 [corr_name] SET 列名 = 值 [, 列名 = 值 ... ] where current of 游標名;
3. 增加記錄
①只有一種類型的增加記錄語句:exec sql insert into 表名 [(列名 [, 列名 ... ])] [values (值 [, 值 ... ]) | 子查詢];
八、狀態捕獲及錯誤處理機制
1. 狀態的概念
①狀態:嵌入式SQL語句的執行狀態,尤其指一些出錯狀態。
②有時程序需要知道這些狀態,並對這些狀態進行處理。
2. 狀態捕獲及處理由三部分組成
①設置SQL通信區:一般在嵌入式SQL程序的開始處設置
- exec sql include sqlca;
②設置狀態捕獲語句:在任何位置都可設置,可多次設置,有其作用域
- exec sql whenever sqlerror goto report_error;
③狀態處理語句:一段程序,用於處理SQL操作的某種狀態
- report_error: exec sql rollback;
3. SQL通信區(SQLCA)
- SQLCA是一個已被聲明過的具C語言的結構形式的內存信息區,其中的成員變量用來記錄SQL語句執行的狀態,便於宿主程序讀取與處理
4. 狀態捕獲語句:exec sql whenever condition action
①whenever語句設置一個“條件陷阱”,其會對作用域內的exec sql語句自動檢查是否滿足條件(由conditon指出)
- sqlerror:檢測是否有sql語句出錯
- not found:執行某一sql語句后,沒有相應的結果記錄出現
- sqlwarning:不是錯誤,但應引起注意
②如果滿足condition,則要采取一些動作(由action指出)
- continue:忽略條件或錯誤,繼續執行
- goto 標號:轉移到標號所指示的語句,去進行相應的處理
- stop:終止程序的執行、撤消當前的工作、斷開數據庫
- do函數或call函數:調用宿主程序的函數進行處理,函數返回后從引發該condition的exec sql語句后繼續執行
③狀態捕獲語句whenever的作用域是其后所有的exec sql語句,一直到程序中出現另一相同條件的whenever語句為止
5. 記錄狀態信息的三種方法
①sqlcode:DBMS提供一個sqlcode變量來記錄SQL語句執行的狀態信息
②sqlca.sqlcode:類似於sqlcode,但其屬於sqlca
③sqlstate:有些DBMS提供該變量來記錄SQL語句執行的狀態信息
④使用這些變量,我們可以明確錯誤類型,從而進行顯式狀態處理