嵌入式SQL和動(dòng)態(tài)SQL的具體使用
基本概述
嵌入式SQL和動(dòng)態(tài)SQL是兩種在應(yīng)用程序中嵌入和使用SQL語(yǔ)句的方法。它們都允許開(kāi)發(fā)人員在編程語(yǔ)言中編寫(xiě)SQL語(yǔ)句,以便在應(yīng)用程序中執(zhí)行數(shù)據(jù)庫(kù)操作。然而,這兩種方法在實(shí)現(xiàn)方式、性能和靈活性方面存在一些差異。
嵌入式SQL是一種將SQL語(yǔ)句直接嵌入到宿主語(yǔ)言(如C、C++、Java等)代碼中的方法。在這種情況下,開(kāi)發(fā)人員需要使用特定的語(yǔ)法和預(yù)處理器來(lái)將SQL語(yǔ)句與宿主語(yǔ)言代碼集成在一起。嵌入式SQL的主要優(yōu)點(diǎn)是它允許開(kāi)發(fā)人員在編寫(xiě)應(yīng)用程序時(shí)使用熟悉的宿主語(yǔ)言語(yǔ)法,同時(shí)仍然能夠利用SQL的強(qiáng)大功能。此外,嵌入式SQL通常具有較好的性能,因?yàn)樗试S編譯器在編譯時(shí)檢查SQL語(yǔ)句的有效性,并生成優(yōu)化的代碼。
動(dòng)態(tài)SQL是一種在運(yùn)行時(shí)構(gòu)建和執(zhí)行SQL語(yǔ)句的方法。在這種情況下,開(kāi)發(fā)人員需要使用字符串拼接或模板引擎等技術(shù)來(lái)動(dòng)態(tài)生成SQL語(yǔ)句。然后,這些語(yǔ)句可以在應(yīng)用程序運(yùn)行時(shí)傳遞給數(shù)據(jù)庫(kù)服務(wù)器進(jìn)行執(zhí)行。動(dòng)態(tài)SQL的主要優(yōu)點(diǎn)是它具有很高的靈活性,因?yàn)樗试S開(kāi)發(fā)人員根據(jù)運(yùn)行時(shí)條件構(gòu)建和修改SQL語(yǔ)句。這使得動(dòng)態(tài)SQL非常適合處理復(fù)雜的查詢和更新操作,以及支持用戶自定義的查詢和報(bào)告功能。然而,動(dòng)態(tài)SQL的性能可能較差,因?yàn)樗枰谶\(yùn)行時(shí)解析和優(yōu)化SQL語(yǔ)句,這可能導(dǎo)致額外的開(kāi)銷。
總的來(lái)說(shuō),嵌入式SQL和動(dòng)態(tài)SQL各有優(yōu)缺點(diǎn)。嵌入式SQL適用于那些需要高性能和編譯時(shí)錯(cuò)誤檢查的場(chǎng)景,而動(dòng)態(tài)SQL適用于那些需要高度靈活性和運(yùn)行時(shí)動(dòng)態(tài)生成SQL語(yǔ)句的場(chǎng)景。在選擇使用哪種方法時(shí),開(kāi)發(fā)人員應(yīng)權(quán)衡這些因素,并根據(jù)應(yīng)用程序的具體需求做出決策。
在實(shí)際開(kāi)發(fā)過(guò)程中,開(kāi)發(fā)人員可能需要結(jié)合使用嵌入式SQL和動(dòng)態(tài)SQL。例如,他們可以使用嵌入式SQL編寫(xiě)大部分?jǐn)?shù)據(jù)庫(kù)操作,以確保高性能和編譯時(shí)錯(cuò)誤檢查;同時(shí),對(duì)于需要高度靈活性的部分,可以使用動(dòng)態(tài)SQL來(lái)實(shí)現(xiàn)。這種混合方法可以充分利用兩種方法的優(yōu)點(diǎn),同時(shí)避免它們的局限性。
嵌入式 SQL
SQL 提供了將 SQL 語(yǔ)句嵌入某種高級(jí)語(yǔ)言中的使用方式,但是如何識(shí)別嵌入在高級(jí)語(yǔ)言中的 SQL 語(yǔ)句,通常采用預(yù)編譯的方法。該方法的關(guān)鍵問(wèn)題是必須區(qū)分主語(yǔ)言中嵌入的 SQL語(yǔ)句,以及主語(yǔ)言和 SQL 間的通信問(wèn)題。采用的方法由 DBMS 的預(yù)處理程序?qū)υ闯绦蜻M(jìn)行掃描,識(shí)別出 SQL 語(yǔ)句,把它們轉(zhuǎn)換為主語(yǔ)言調(diào)用語(yǔ)句,以使主語(yǔ)言編譯程序能識(shí)別它,最后由主語(yǔ)言的編譯程序?qū)⒄麄€(gè)源程序編譯成目標(biāo)碼。
如何區(qū)分主語(yǔ)言語(yǔ)句與 SQL 語(yǔ)句?
需要在所有的 SQL 語(yǔ)句前加前綴 EXEC SQL
,而 SQL 的結(jié)束標(biāo)志隨主語(yǔ)言的不同而不同。
- PL/1 和 C 語(yǔ)言的引用格式為:
EXEC SQL <SQL語(yǔ)句>
; - COBOL 語(yǔ)言的引用格式為:
EXEC SQL <SQL 語(yǔ)句> END-EXEC
;
主語(yǔ)言與數(shù)據(jù)庫(kù)如何通信?
(1)SQL 通信區(qū) (SQL Communication Area,SQLCA) 向主語(yǔ)言傳遞 SQL 語(yǔ)句執(zhí)行的狀態(tài)信息,使主語(yǔ)言能夠根據(jù)此信息控制程序流程。
(2)主變量也稱共享變量。主語(yǔ)言向 SQL 語(yǔ)句提供參數(shù)主要通過(guò)主變量,主變量由主語(yǔ)言的程序定義,并用 SQL 的 DECLARE 語(yǔ)句說(shuō)明,引用變量一定要加上:
。
EXEC SQL BEGIN DECLARE SECTION; /*說(shuō)明主變量*/ char Msno[4],Mcno[3],Givensno[5]; int Mgrade; char SQLSTATE[6]; EXEC SQL END DECLARE SECTION;
分析:以上說(shuō)明了五個(gè)共享變量,其中,SQLSTATE 是一個(gè)特殊的共享變量,解釋 SQL 語(yǔ)句執(zhí)行狀況的作用。當(dāng) SQL 語(yǔ)句執(zhí)行成功時(shí),系統(tǒng)自動(dòng)給 SQLSTATE 賦值上全零值,否則為非全零(”02000”)。因此,當(dāng)執(zhí)行一條SQL語(yǔ)句后,可以根據(jù) SQLSTATE 的值轉(zhuǎn)向不同的分支,以控制程序的流向。引用時(shí),為了與 SQL 屬性名相區(qū)別,需在主變量前加:
。
示例1. 根據(jù)共享變量 givensno 值查詢學(xué)生關(guān)系students 中學(xué)生的姓名、年齡和性別。
EXEC SQL SELECT sname,age,sex INTO :Msno,Mcno,:givensno FROM students WHERE sno=:Msno;
示例2. 某學(xué)生選修了一門(mén)課程信息,將其插入學(xué)生選課表SC中,假設(shè)學(xué)號(hào)、課程號(hào)、成績(jī)已分別賦給主變量HSno、Hcno和Hgrade。
EXEC SQL INSERT INTO SC(Sno,Cno,Grade) VALUES(:Hsno,:Hcno,:Hgrade);
(3)游標(biāo)。SQL 語(yǔ)言是面向集合的,一條 SQL 語(yǔ)句可產(chǎn)生或處理多條記錄。而主語(yǔ)言是面向記錄的,一組主變量一次只能放一條記錄,所以,引入游標(biāo),通過(guò)移動(dòng)游標(biāo)指針來(lái)決定獲取哪一條記錄。
- 定義游標(biāo):說(shuō)明性語(yǔ)句,定義中的 SELECT 語(yǔ)句并不立即執(zhí)行。語(yǔ)法如下:
EXEC SQL DECLARE <游標(biāo)名> CURSOR FOR <SELECT 語(yǔ)句>
- 打開(kāi)游標(biāo):執(zhí)行游標(biāo)定義中的 SELECT 語(yǔ)句,同時(shí)游標(biāo)處于活動(dòng)狀態(tài),游標(biāo)是一個(gè)指針,此時(shí)指向查詢結(jié)果的第一行之前。語(yǔ)法如下:
EXEC SQL OPEN <游標(biāo)名>
- 推進(jìn)游標(biāo):使用時(shí),游標(biāo)會(huì)推進(jìn)一行,并把指針指向的行(稱為當(dāng)前行)中的值取出,送到共享變量中。變量表由逗號(hào)分開(kāi)的共享變量組成。該語(yǔ)句經(jīng)常用于宿主程序的循環(huán)結(jié)構(gòu)中,并借助宿主語(yǔ)言的處理語(yǔ)句逐一處理查詢結(jié)果中的一個(gè)元組。語(yǔ)法如下:
EXEC SQL FETCH FROM <游標(biāo)名> INTO <變量表>
- 關(guān)閉游標(biāo):使用時(shí),關(guān)閉游標(biāo),不再和查詢結(jié)果相聯(lián)系。關(guān)閉了的游標(biāo),可以再次打開(kāi),與新的查詢結(jié)果相聯(lián)系。在游標(biāo)處于活動(dòng)狀態(tài)時(shí),可以修改和刪除游標(biāo)指向的元組。語(yǔ)法如下:
EXEC SQL CLOSE <游標(biāo)名>
示例3. 在C語(yǔ)言中嵌入SQL的查詢,檢索某學(xué)生的學(xué)習(xí)成績(jī),其學(xué)號(hào)由共享主變量givensno給出,結(jié)果放在主變量Sno,Cno,Grade中。如果成績(jī)不及格,則刪除該記錄,如果成績(jī)?yōu)?0~69分,則將成績(jī)修改為70分,并顯示學(xué)生的成績(jī)信息(除60分以下的)
#DEFINE NO_MORE_TUPLES !(strcmp(SQLSTATE,"02000")) void sel() {EXEC SQL BEGIN DECLARE SECTION; /*說(shuō)明主變量*/ char Msno[4],Mcno[3],givensno[5]; int Mgrade; char SQLSTATE[6]; EXEC SQL END DECLARE SECTION; EXEC SQL DECLARE Scx CURSOR FOR /* 說(shuō)明游標(biāo)Scx,將查詢結(jié)果與Scx建立聯(lián)系*/ SELECT Sno,Cno,Grade FROM SC WHERE Sno=:givensno; EXEC SQL OPEN Scx; While(1) /* 用循環(huán)結(jié)構(gòu)逐條處理結(jié)果集中的記錄*/ {EXEC SQL FETCH FROM Scx /* 游標(biāo)推進(jìn)一行*/ INTO :Msno,:Mcno,:Mgrade; /* 送入主變量,注意每個(gè)變量要加分號(hào);*/ if (NO_MORE_TUPLES) Break; /* 處理完退出循環(huán)*/ print("%s,%s,%d\n",sno,cno,g); }; if (Mgrade<60) /* 成績(jī)<60*/ EXEC SQL DELETE FROM SC WHERE CURRENT OF Scx; Else {if (Mgrade < 70) /* 成績(jī)<70*/ EXEC SQL UPDATE SC SET grade = 70 WHERE CURRENT OF Scx; MGrade = 70 } Printf("%s,%s,%d",Msno,Mcno,Mgrade); /*顯示學(xué)生記錄*/ EXEC SQL CLOSE Scx; /* 關(guān)閉游標(biāo)*/ };
動(dòng)態(tài) SQL
動(dòng)態(tài) SQL 允許程序在運(yùn)行時(shí)構(gòu)造、提交 SQL 查詢。使用動(dòng)態(tài) SQL 語(yǔ)句時(shí),還可以改進(jìn)技術(shù);當(dāng)預(yù)備語(yǔ)句組合而成的 SQL 語(yǔ)句只需執(zhí)行一次, 那么預(yù)備語(yǔ)句可以在程序運(yùn)行時(shí)由用戶輸入才組合起來(lái),但并不執(zhí)行。
動(dòng)態(tài) SQL 預(yù)備語(yǔ)句格式
EXEC SQL PREPARE <動(dòng)態(tài)SQL語(yǔ)句名> FROM <共享變量或字符串>;
動(dòng)態(tài) SQL 執(zhí)行語(yǔ)句格式
EXEC SQL EXECUTE <動(dòng)態(tài)SQL語(yǔ)句名>;
示例4. 動(dòng)態(tài) SQL 示例
char*query = "UPDATE sc SET Grade = Grade*1.1 WHERE Cno = ?"; EXEC SQL PREPARE dynprog FROM :query; char cno[5] = "C4"; EXEC SQL EXECUTE dynprog USING :cno;
總結(jié)
嵌入式SQL和動(dòng)態(tài)SQL是兩種在應(yīng)用程序中嵌入和使用SQL語(yǔ)句的方法。它們各自具有一定的優(yōu)勢(shì)和局限性,適用于不同的場(chǎng)景。開(kāi)發(fā)人員應(yīng)根據(jù)應(yīng)用程序的具體需求選擇合適的方法,并在必要時(shí)結(jié)合使用這兩種方法,以實(shí)現(xiàn)最佳的性能和靈活性。
到此這篇關(guān)于嵌入式SQL和動(dòng)態(tài)SQL的具體使用的文章就介紹到這了,更多相關(guān)嵌入式SQL和動(dòng)態(tài)SQL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
必須會(huì)的SQL語(yǔ)句(二) 創(chuàng)建表、修改表結(jié)構(gòu)、刪除表
這篇文章主要介紹了sqlserver中創(chuàng)建表、修改表結(jié)構(gòu)、刪除表的sql語(yǔ)句,需要的朋友可以參考下2015-01-01sqlserver 數(shù)據(jù)庫(kù)連接字符串中的可選項(xiàng)收集
sqlserver 數(shù)據(jù)庫(kù)連接字符串中的可選項(xiàng)收集,需要的朋友可以參考下。2011-10-10jdbc連接sql server數(shù)據(jù)庫(kù)問(wèn)題分析
SQL Server連接中問(wèn)題還真多。不進(jìn)行設(shè)置還真連接不上,這里總結(jié)一下,需要的朋友可以參考2012-12-12