嵌入式SQL語(yǔ)言:內(nèi)容提要
4.1 嵌入式SQL語(yǔ)言簡(jiǎn)述
4.2嵌入式SQL語(yǔ)言的基本處理技巧
4.3 嵌入式程序中SQL語(yǔ)句的基本操作方式
4.4 動(dòng)態(tài)SQL簡(jiǎn)介
4.1嵌入式SQL語(yǔ)言簡(jiǎn)述
-
交互式SQL語(yǔ)言的局限
現(xiàn)實(shí)中有些特別復(fù)雜的檢索結(jié)果難以用一條交互式SQL語(yǔ)句完成,此時(shí)需要結(jié)合高級(jí)語(yǔ)言中經(jīng)常出現(xiàn)的順序、分支和循環(huán)結(jié)構(gòu)來(lái)幫助處理
例如: 依據(jù)不同條件執(zhí)行不同的檢索操作等
If some-condition Then
SQL-Query1
Else
SQL-Query2
EndIf
再如: 控制檢索操作執(zhí)行的順序
Do While some-condition
SQL-Query
EndDo
嵌入式SQL語(yǔ)言
將SQL語(yǔ)言嵌入到某一種高級(jí)語(yǔ)言中使用
這種高級(jí)語(yǔ)言,如C/C++, Java等,又稱(chēng)宿主語(yǔ)言
嵌入在宿主語(yǔ)言中的SQL與前面介紹的交互式SQL有一些不同的操作方式嵌入式SQL語(yǔ)言與交互式SQL語(yǔ)言
交互式SQL語(yǔ)言:
select Sname, Sage from Student
where Sname=‘張三’;
嵌入式SQL語(yǔ)言: 以宿主語(yǔ)言C語(yǔ)言為例
exec sql
select Sname, Sage into :vSname, :vSage from Student
where Sname=‘張三’;
-
上述嵌入式SQL語(yǔ)言的特性
exec sql引導(dǎo)SQL語(yǔ)句:
提供給C編譯器,以便對(duì)SQL語(yǔ)句預(yù)編譯成C編譯器可識(shí)別的語(yǔ)句
增加 into 子句:
該子句用于指出接收SQL語(yǔ)句檢索結(jié)果的程序變量
由冒號(hào)引導(dǎo)的程序變量:
如: ‘:vSname’, ‘:vSage’
4.2嵌入式SQL語(yǔ)言的基本處理技巧
4.2.1變量的聲明與使用
- 在嵌入式SQL語(yǔ)句中可以出現(xiàn)宿主語(yǔ)言語(yǔ)句所使用的變量
exec sql
select Sname, Sage into :vSname, :vSage from Student
where Sname=‘張三’;
- 這些變量需要特殊的聲明,如下所示
exec sql
begin declare section;
char vSname[10], specName[10]=“張三”;
int vSage;
exec sql
end declare section;
PS:要注意宿主程序的字符串變量長(zhǎng)度應(yīng)比字符型字段的長(zhǎng)度多1個(gè),因宿主程序的字符串尾部多一個(gè)終止符為‘\0‘,而程序中用雙引號(hào)來(lái)描述
-
變量的使用
聲明的變量,可以在宿主程序中賦值,然后傳遞給SQL語(yǔ)句的where等子句中,以使SQL語(yǔ)句能夠按照指定的要求(可變化的)進(jìn)行檢索
exec sql
begin declare section;
char vSname[10], specName[10]=“張三”;
int vSage;
exec sql
end declare section;
exec sql
select Sname, Sage into :vSname, :vSage from Student
where Sname = :specName
4.2.2程序與數(shù)據(jù)庫(kù)的連接與斷開(kāi)
-
數(shù)據(jù)庫(kù)連接
在嵌入式SQL程序執(zhí)行之前,首先要與數(shù)據(jù)庫(kù)進(jìn)行連接 - SQL標(biāo)準(zhǔn)中建議的連接語(yǔ)法為
exec sql
connect to target-server as
connect-name user user-name;
或
exec sql connect to default;
- Oracle中數(shù)據(jù)庫(kù)連接
connect :user_name identified by:user_pwd;
- DB2 UDB中數(shù)據(jù)庫(kù)連接:
connect to mydbuser :user_name using :user_pwd
- 數(shù)據(jù)庫(kù)斷開(kāi)
- SQL標(biāo)準(zhǔn)中建議的斷開(kāi)連接的語(yǔ)法為
exec sql disconnect connect-name;
或
exec sql disconnect current;
- Oracle中斷開(kāi)數(shù)據(jù)庫(kù)連接
exec sql commit release;
或
exec sql rollback release;
- DB2 UDB中斷開(kāi)數(shù)據(jù)庫(kù)連接
exec sql connect reset;
4.2.3 SQL結(jié)果的提交與撤消
-
簡(jiǎn)述
SQL語(yǔ)句在程序執(zhí)行過(guò)程中,必須有提交和撤消語(yǔ)句才能確認(rèn)其操作結(jié)果 - SQL結(jié)果的提交
exec sql commit work;
- SQL結(jié)果的撤消
exec sql rollback work;
為此
很多DBMS都設(shè)計(jì)了捆綁提交/撤消與斷開(kāi)連接在一起的語(yǔ)句,以保證在斷開(kāi)連接之前使用戶(hù)確認(rèn)提交或撤消先前的工作
- 例如Oracle中:
exec sql commit release;
或
exec sql rollback release;
4.2.4單行結(jié)果處理與多行結(jié)果處理的差異Into子句與游標(biāo)(Cursor)
-
單行結(jié)果
單行檢索結(jié)果的處理,可以直接使用
select...into...
嵌入式select語(yǔ)句中引入into子句,只能保留和處理單行結(jié)果
exec sql
select Sno, Sname, Sclass into :vSno, :vSname, :vSclass
from Student
where Sname=‘張三’;
多行檢索結(jié)果的處理則需使用游標(biāo)
讀一行操作是通過(guò)Fetch...into語(yǔ)句實(shí)現(xiàn)的:
每一次Fetch, 都是先向下移動(dòng)指針,然后再讀取
記錄集有結(jié)束標(biāo)識(shí)EOF, 用來(lái)標(biāo)記前面和后面已沒(méi)有記錄了游標(biāo)檢索示例
exec sql
declare cur_student cursor for
select Sno, Sname, Sclassfrom Student
where Sclass=‘035101’ ;
#檢索出所有calss為035101的元組
exec sql open cur_student;
exec sql fetch cur_student
into :vSno, :vSname, :vSclass;......
exec sql close cur_student;
PS:游標(biāo)可以定義一次,多次打開(kāi)(多次執(zhí)行),多次關(guān)閉
4.2.5 狀態(tài)捕獲及其處理
簡(jiǎn)述
狀態(tài),是嵌入SQL語(yǔ)句的執(zhí)行狀態(tài),尤其指一些出錯(cuò)狀態(tài);有時(shí)程序需要知道這些狀態(tài)并對(duì)這些狀態(tài)進(jìn)行處理設(shè)置SQL通信區(qū):
一般在嵌入式SQL程序的開(kāi)始處便設(shè)置
exec sql include sqlca;
PS: SQL通信區(qū): SQLCA
SQLCA是一個(gè)已被聲明過(guò)的具C結(jié)構(gòu)形式的內(nèi)存信息區(qū),其中的成員變量用來(lái)記錄SQL語(yǔ)句執(zhí)行的狀態(tài),便于宿主程序讀取與處理
SQLCA是DBMS(執(zhí)行SQL語(yǔ)句)與宿主程序之間交流的橋梁之一
-
設(shè)置狀態(tài)捕獲語(yǔ)句:
在嵌入式SQL程序的任何位置都可設(shè)置;可多次設(shè)置;但有作用域
exec sql whenever
sqlerror goto report_error;
PS:
exec sql whenever condition action;
Whenever語(yǔ)句的作用是設(shè)置一個(gè)“條件陷阱”, 該條語(yǔ)句會(huì)對(duì)其后面的所有由Exec SQL語(yǔ)句所引起的對(duì)數(shù)據(jù)庫(kù)系統(tǒng)的調(diào)用自動(dòng)檢查它是否滿(mǎn)足條件(由condition指出)
SQLERROR:檢測(cè)是否有SQL語(yǔ)句出錯(cuò)。其具體意義依賴(lài)于特定的DBMS
NOT FOUND:執(zhí)行某一SQL語(yǔ)句后,沒(méi)有相應(yīng)的結(jié)果記錄出現(xiàn)
SQLWARNING:不是錯(cuò)誤,但應(yīng)引起注意的條件
condition:如果滿(mǎn)足condition 則要采取一些動(dòng)作(由action指出)
CONTINUE:忽略條件或錯(cuò)誤,繼續(xù)執(zhí)行
GOTO標(biāo)號(hào):轉(zhuǎn)移到標(biāo)號(hào)所指示的語(yǔ)句,去進(jìn)行相應(yīng)的處理
STOP:終止程序運(yùn)行、撤消當(dāng)前的工作、斷開(kāi)數(shù)據(jù)庫(kù)的連接
DO函數(shù)或CALL函數(shù):調(diào)用宿主程序的函數(shù)進(jìn)行處理,函數(shù)返回后從引發(fā)該condition的ExecSQL語(yǔ)句之后的語(yǔ)句繼續(xù)進(jìn)行
-
狀態(tài)處理語(yǔ)句:
某一段程序以應(yīng)對(duì)SQL操作的某種狀態(tài)
report_error:
exec sql rollback
4.2.6典型DBMS系統(tǒng)記錄狀態(tài)信息的三種方法
- 狀態(tài)記錄:sqlcode、sqlca.sqlcode、sqlstate
sqlcode:
典型DBMS都提供一個(gè)sqlcode變量來(lái)記錄其執(zhí)行sql語(yǔ)句的狀態(tài):
sqlcode== 0, successful call;
sqlcode< 0, error, e.g., from connect, database does not exist;
sqlcode>0, warning, e.g., no rows retrieved from fetch
sqlca.sqlcode:一個(gè)存儲(chǔ)信息的對(duì)象,包
sqlca.sqlcode: 支持sqlca的產(chǎn)品一般要在sqlca中填寫(xiě)sqlcode來(lái)記錄上述信息; 除此而外,sqlca還有其他狀態(tài)信息的記錄
sqlca是一個(gè)存儲(chǔ)區(qū)域,將統(tǒng)計(jì)和錯(cuò)誤從應(yīng)用程序傳遞到數(shù)據(jù)庫(kù)服務(wù)器再傳回應(yīng)用程序的每個(gè)數(shù)據(jù)庫(kù)請(qǐng)求會(huì)使用它;
sqlca用作應(yīng)用程序到數(shù)據(jù)庫(kù)的通信鏈接的句柄。它會(huì)被傳遞到需要與數(shù)據(jù)庫(kù)服務(wù)器進(jìn)行通信的所有數(shù)據(jù)庫(kù)庫(kù)函數(shù)中;
它會(huì)在所有嵌入式SQL語(yǔ)句上被隱式傳遞
sqlstate: 有些DBMS提供的記錄狀態(tài)信息的變量是sqlstate或sqlca.sqlstate
4.3 嵌入式程序中SQL語(yǔ)句的基本操作方式
4.3.1 Select語(yǔ)句的基本操作
exec sql select Sname, Sage
into :vSname, :vSage from Student
where Sname= :specName;
4.3.2 Delete語(yǔ)句的基本操作
- 查找刪除與定位刪除:
查找刪除:
exec sql delete from customers c
where c.city= ‘harbin’ and not exists
( select *from orders o where o.cid= c.cid);
定位刪除:
exec sql declare delcust cursor
for select cid from customers c
where c.city=‘harbin’ and not exists
( select *from orders o where o.cid= c.cid)
for update of cid;
exec sql open delcust
While (true)
{
exec sql fetch delcust
into :cust_id;exec sql
delete from customers
where current of delcust;
}
4.3.3 Update語(yǔ)句的基本操作
- 查找更新與定位更新:
查找更新:
exec sql
update students set sclass= ‘035102’
where s.sclass= ‘034101’
定位更新:
exec sql declare stud cursor
for select * from student s
where s.sclass=‘034101’
for update of sclass;
exec sqlopen stud
While (true)
{
exec sqlfetch stud
into :vSno, :vSname, :vSclass;
exec sql
update student set sclass= ‘035102’
where current of stud; }
4.3.6 Insert語(yǔ)句的基本操作
exec sql
insert into student ( sno, sname, sclass)
values (‘03510128’, ‘張三’, ‘035101’) ;
4.3.5 Cursor相關(guān)語(yǔ)句的基本操作
exec sql declare cur_student cursor
for select Sno, Sname, Sclass from Student
where Sclass= :vClass
order by Snofor read only ;
- Cursor的打開(kāi)和關(guān)閉:
open cursor / close cursor
exec sql open cursor_name;
exec sql close cursor_name;
- 數(shù)據(jù)讀?。篎etch
exec sql declare cur_student cursor
for select Sno, Sname, Sclass from Student
where Sclass= :vClass
order by Snofor read only ;
exec sql open cur_student;
exec sql fetch cur_student
into :vSno, :vSname, :vSage
exec sql close cur_student;
- 可滾動(dòng)cursor示例:
exec sq lfetch
[next | prior | first | last | [absolute | relative]value_spec]
from cursor_name
into host-variable [, host-variable ...];
next:向結(jié)束方向移動(dòng)一條;
prior:向開(kāi)始方向移動(dòng)一條;
first:回到第一條;
last:移動(dòng)到最后一條;
absolutvalue_spec:定向檢索指定位置的行,value_spec由1至當(dāng)前記錄集最大值;
relativevalue_spec:相對(duì)當(dāng)前記錄向前或向后移動(dòng),value_spec為正數(shù)向結(jié)束方向移動(dòng),為負(fù)數(shù)向開(kāi)始方向移動(dòng)
4.4 動(dòng)態(tài)SQL簡(jiǎn)介
4.4.1動(dòng)態(tài)SQL的概念和作用
4.4.2動(dòng)態(tài)SQL的兩種執(zhí)行方式
4.4.3更為復(fù)雜的動(dòng)態(tài)SQL