數(shù)據(jù)庫(kù)——嵌入式SQL
??? 使用嵌入式SQL,必須解決如下幾個(gè)問(wèn)題:
??? (1)SQL語(yǔ)言和宿主語(yǔ)言的數(shù)據(jù)類型可能不完全一致,必須解決數(shù)據(jù)類型的轉(zhuǎn)換問(wèn)題,這與DBMS和其支持的宿主語(yǔ)言有關(guān)。
??? (2)用SQL語(yǔ)句查詢數(shù)據(jù)庫(kù)的結(jié)果是元組的集合,而宿主語(yǔ)言只支持?jǐn)?shù)字型、字符性、數(shù)組和記錄等數(shù)據(jù)類型,不支持集合和關(guān)系類型。 為此,要通過(guò)SQL語(yǔ)句使用的宿主變量逐個(gè)地把每個(gè)元組傳遞給宿主語(yǔ)言中的程序變量。宿主語(yǔ)言編譯器不能識(shí)別和接受在宿主語(yǔ)言中的SQL語(yǔ)句代碼,必須把嵌入有SQL 語(yǔ)句的宿主語(yǔ)言程序翻譯成標(biāo)準(zhǔn)的宿主語(yǔ)言語(yǔ)句再進(jìn)行編譯,或直接產(chǎn)生可執(zhí)行的代碼,這是首先要解決的問(wèn)題。為此,通常先對(duì)嵌入有SQL語(yǔ)句的宿主語(yǔ)言程序進(jìn)行預(yù)處理,翻譯成標(biāo)準(zhǔn)的宿主語(yǔ)言語(yǔ)句,再用宿主語(yǔ)言編譯器進(jìn)行編譯。數(shù)據(jù)庫(kù)和宿主語(yǔ)言之間如何通過(guò)宿主變量傳遞數(shù)據(jù)和信息。
??? (3)在宿主語(yǔ)言程序中如何判斷SQL語(yǔ)句執(zhí)行的正確或錯(cuò)誤?
??? (2)用SQL語(yǔ)句查詢數(shù)據(jù)庫(kù)的結(jié)果是元組的集合,而宿主語(yǔ)言只支持?jǐn)?shù)字型、字符性、數(shù)組和記錄等數(shù)據(jù)類型,不支持集合和關(guān)系類型。 為此,要通過(guò)SQL語(yǔ)句使用的宿主變量逐個(gè)地把每個(gè)元組傳遞給宿主語(yǔ)言中的程序變量。宿主語(yǔ)言編譯器不能識(shí)別和接受在宿主語(yǔ)言中的SQL語(yǔ)句代碼,必須把嵌入有SQL 語(yǔ)句的宿主語(yǔ)言程序翻譯成標(biāo)準(zhǔn)的宿主語(yǔ)言語(yǔ)句再進(jìn)行編譯,或直接產(chǎn)生可執(zhí)行的代碼,這是首先要解決的問(wèn)題。為此,通常先對(duì)嵌入有SQL語(yǔ)句的宿主語(yǔ)言程序進(jìn)行預(yù)處理,翻譯成標(biāo)準(zhǔn)的宿主語(yǔ)言語(yǔ)句,再用宿主語(yǔ)言編譯器進(jìn)行編譯。數(shù)據(jù)庫(kù)和宿主語(yǔ)言之間如何通過(guò)宿主變量傳遞數(shù)據(jù)和信息。
??? (3)在宿主語(yǔ)言程序中如何判斷SQL語(yǔ)句執(zhí)行的正確或錯(cuò)誤?
??? 下面對(duì)這些問(wèn)題逐一給出解答。
1.嵌入式SQL語(yǔ)言的使用格式
??? 為了把SQL語(yǔ)句嵌入主程序設(shè)計(jì)語(yǔ)言中,并且在主程序設(shè)計(jì)語(yǔ)言的源代碼中能夠區(qū)分宿主語(yǔ)言的語(yǔ)句和嵌入的SQL語(yǔ)句,便于預(yù)處理程序識(shí)別它,必須有開始和結(jié)束的語(yǔ)句塊標(biāo)識(shí)符,把SQL語(yǔ)句括在其中。通常在SQL語(yǔ)句前面加上前綴表示"EXEC SQL",并以"END_EXEC"作為語(yǔ)句結(jié)束的標(biāo)志,構(gòu)成EXEC SQL <SQL 語(yǔ)句> END_EXEC的嵌入語(yǔ)句塊,如下所示:
?
開始標(biāo)識(shí)符:'EXEC SQL'
<嵌入的SQL語(yǔ)句>
結(jié)束標(biāo)識(shí)符:'END_SQL'
<嵌入的SQL語(yǔ)句>
結(jié)束標(biāo)識(shí)符:'END_SQL'
??? 說(shuō)明:SQL語(yǔ)句的結(jié)束標(biāo)志隨著宿主語(yǔ)言的不同而有差別。因此,嵌入式SQL的確切語(yǔ)法依賴于宿主語(yǔ)言。當(dāng)宿主語(yǔ)言為C、PL/1或Pascal時(shí),嵌入語(yǔ)句塊的結(jié)束符使用分號(hào)';',不使用'END_SQL'。
Oracle數(shù)據(jù)庫(kù)系統(tǒng)提供了Pro*C語(yǔ)言,在C語(yǔ)言中可嵌入SQL語(yǔ)句,以分號(hào)';'作為結(jié)束標(biāo)識(shí)符。為了方便起見,下面的示例程序中,嵌入語(yǔ)句塊以EXEC SQL開始,用分號(hào)';'作為結(jié)束標(biāo)志。
2.共享主變量的聲明
??? 凡在SQL語(yǔ)句中使用的、用于與宿主語(yǔ)言交換數(shù)據(jù)的變量,稱為宿主變量,簡(jiǎn)稱主變量。主變量也必須用開始和結(jié)束標(biāo)識(shí)符括起來(lái)進(jìn)行聲明。只有這樣聲明的主變量才能用于SQL與宿主語(yǔ)言交換數(shù)據(jù),所以主變量是SQL和宿主語(yǔ)言共享的變量。
??? 主變量是主語(yǔ)言的變量,所以主變量的說(shuō)明必須遵從宿主語(yǔ)言的規(guī)定,但主變量類型必須是兩種語(yǔ)言都能處理的。
主變量的聲明格式:EXEC SQL BEGIN DECLARE SECTION
<SQL 宿主變量說(shuō)明>
EXEC SQL END DECLARE SECTION
<SQL 宿主變量說(shuō)明>
EXEC SQL END DECLARE SECTION
這些共享的變量在宿主語(yǔ)言中使用時(shí)同其他變量一樣,當(dāng)在SQL語(yǔ)句中使用宿主變量時(shí),宿主變量前必須要冠以某種特殊符號(hào),用以區(qū)別宿主變量和SQL語(yǔ)句中的列名。Oracle的宿主變量前使用冒號(hào)':',SQL Server中使用
'@'
符號(hào)。例如,@xy,@post等,稱為SQL Server的局部變量。
在SQL中可以使用共享宿主變量實(shí)現(xiàn)與宿主語(yǔ)言之間傳遞具體的值。下面的例子是在C語(yǔ)言中嵌入SQL語(yǔ)句,使用共享宿主變量時(shí)在前面加上冒號(hào)。
例1:聲明三個(gè)主變量,如下描述:
?
EXEC SQL BEGIN DECLARE SECTION
Char sname[20], ssex[1];
Char sclass[10];
EXEC SQL END DECLARE SECTION
Char sname[20], ssex[1];
Char sclass[10];
EXEC SQL END DECLARE SECTION
??? 說(shuō)明:上面的例子夾在嵌入式SQL標(biāo)識(shí)語(yǔ)句之間的是宿主變量的聲明,只有宿主語(yǔ)言和SQL都能處理的變量類型才有意義。中間的語(yǔ)句說(shuō)明了三個(gè)變量 sname,ssex,sclass,都是字符數(shù)組,用來(lái)保存學(xué)生的姓名、性別、班級(jí)編號(hào)。它們的說(shuō)明形式必須遵從宿主語(yǔ)言的規(guī)定。例如,上面的例子中,就是因?yàn)樗拗髡Z(yǔ)言是C語(yǔ)言而采用的說(shuō)明形式。
3.特殊的系統(tǒng)變量
?
??? 每個(gè)數(shù)據(jù)庫(kù)管理系統(tǒng)都提供一個(gè)專用的系統(tǒng)變量SQLSTATE,記錄SQL語(yǔ)句執(zhí)行的狀態(tài)。每當(dāng)執(zhí)行完一個(gè)SQL語(yǔ)句之后,一個(gè)代碼便被放入到該系統(tǒng)變量SQLSTATE中,該代碼標(biāo)識(shí)SQL語(yǔ)句執(zhí)行情況。在程序中,要使用SQLSTATE主變量,也必須要事先說(shuō)明,并在每一個(gè)SQL語(yǔ)句之后,檢驗(yàn)SQLSTATE 的狀態(tài),判斷SQL語(yǔ)句的執(zhí)行結(jié)果。
?
SQLSTATE 的狀態(tài)碼為:
SQLSTATE='00000' 表示執(zhí)行正確,
SQLSTATE='02000' 表示沒(méi)有滿足要求的元組。
SQLSTATE='02000' 表示沒(méi)有滿足要求的元組。
?
說(shuō)明SQLSTATE主變量示例:
EXEC SQL BEGIN DECLARE SECTION ;
char SQLSTATE [6]; // 5個(gè)字符和一個(gè)空字符
EXEC SQL END DECLARE SECTION;
EXEC SQL BEGIN DECLARE SECTION ;
char SQLSTATE [6]; // 5個(gè)字符和一個(gè)空字符
EXEC SQL END DECLARE SECTION;
?
檢查SQLSTATE主變量的返回值示例:
EXEC SQL WHENEVER <條件><動(dòng)作>
EXEC SQL WHENEVER <條件><動(dòng)作>
?
其中:
條件:為'NOT FOUND'(02000) 或'SQLERROR'(其他碼)
動(dòng)作:為CONTINUE(繼續(xù)執(zhí)行) 或 GO TO<語(yǔ)句標(biāo)號(hào)>
條件:為'NOT FOUND'(02000) 或'SQLERROR'(其他碼)
動(dòng)作:為CONTINUE(繼續(xù)執(zhí)行) 或 GO TO<語(yǔ)句標(biāo)號(hào)>
在宿主語(yǔ)言程序中,依據(jù)專用的系統(tǒng)變量的值就可以判斷SQL語(yǔ)句執(zhí)行的正確與否。如果SELECT語(yǔ)句沒(méi)有查到記錄,系統(tǒng)就會(huì)把一個(gè)錯(cuò)誤代碼寫入相應(yīng)系統(tǒng)變量SQLSTATE中,SQLSTATE='00000'表示執(zhí)行正確。
?
?
?