




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第8章 數(shù)據(jù)庫(kù)編程 第第8章章 數(shù)據(jù)庫(kù)編程數(shù)據(jù)庫(kù)編程 8.1 嵌入式嵌入式SQL 8.2 存儲(chǔ)過(guò)程存儲(chǔ)過(guò)程 8.3 ODBC編程編程 第8章 數(shù)據(jù)庫(kù)編程 8.1 嵌入式嵌入式SQL SQL語(yǔ)言提供了兩種不同的使用方式:語(yǔ)言提供了兩種不同的使用方式:交互式、嵌交互式、嵌入式入式。 引入嵌入式引入嵌入式SQL的原因?的原因? 1 1)SQLSQL語(yǔ)言是非過(guò)程性語(yǔ)言語(yǔ)言是非過(guò)程性語(yǔ)言 2 2)事務(wù)處理應(yīng)用需要高級(jí)語(yǔ)言)事務(wù)處理應(yīng)用需要高級(jí)語(yǔ)言 交互式交互式SQLSQL和嵌入式和嵌入式SQLSQL這兩種方式細(xì)節(jié)上有差別,這兩種方式細(xì)節(jié)上有差別,在程序設(shè)計(jì)的環(huán)境下,在程序設(shè)計(jì)的環(huán)境下,SQLSQL語(yǔ)句要
2、做某些必要的擴(kuò)充。語(yǔ)句要做某些必要的擴(kuò)充。第8章 數(shù)據(jù)庫(kù)編程 8.1.1 嵌入式嵌入式SQL的處理過(guò)程的處理過(guò)程 嵌入式嵌入式SQLSQL是是將將SQL語(yǔ)句嵌入程序設(shè)計(jì)語(yǔ)言中,被嵌入語(yǔ)句嵌入程序設(shè)計(jì)語(yǔ)言中,被嵌入的程序設(shè)計(jì)語(yǔ)言,如的程序設(shè)計(jì)語(yǔ)言,如C、FORTRAN、C+、Java,稱為,稱為宿宿主語(yǔ)言,簡(jiǎn)稱主語(yǔ)言。主語(yǔ)言,簡(jiǎn)稱主語(yǔ)言。 對(duì)對(duì)ESQL,DBMS可采用兩種方法處理:可采用兩種方法處理: 1 1)預(yù)編譯)預(yù)編譯 2 2)修改和擴(kuò)充主語(yǔ)言使之能處理修改和擴(kuò)充主語(yǔ)言使之能處理SQL語(yǔ)句語(yǔ)句 目前目前采用較多的是預(yù)編譯的方法。即由采用較多的是預(yù)編譯的方法。即由DBMS的預(yù)處的預(yù)處理程序?qū)?/p>
3、源程序進(jìn)行掃描,識(shí)別出理程序?qū)υ闯绦蜻M(jìn)行掃描,識(shí)別出SQL語(yǔ)句,把它們轉(zhuǎn)換語(yǔ)句,把它們轉(zhuǎn)換成主語(yǔ)言調(diào)用語(yǔ)句,以使主語(yǔ)言編譯程序能識(shí)別它,最后成主語(yǔ)言調(diào)用語(yǔ)句,以使主語(yǔ)言編譯程序能識(shí)別它,最后由主語(yǔ)言的編譯程序?qū)⒄麄€(gè)源程序編譯成目標(biāo)碼。由主語(yǔ)言的編譯程序?qū)⒄麄€(gè)源程序編譯成目標(biāo)碼。 第8章 數(shù)據(jù)庫(kù)編程 主語(yǔ)言程序 含ESQL語(yǔ)句RDBMS的預(yù)處理程序ESQL語(yǔ)句轉(zhuǎn)換為函數(shù)調(diào)用主語(yǔ)言編譯程序目標(biāo)語(yǔ)言程序ESQL基本處理過(guò)程 在在ESQL中,為了能夠區(qū)分中,為了能夠區(qū)分SQL語(yǔ)句與主語(yǔ)言語(yǔ)句,所語(yǔ)句與主語(yǔ)言語(yǔ)句,所有有SQL語(yǔ)句都必須加前綴語(yǔ)句都必須加前綴EXEC SQL,以(,以(;)結(jié)束成為一)結(jié)
4、束成為一個(gè)程序片段。個(gè)程序片段。 EXEC SQL; 第8章 數(shù)據(jù)庫(kù)編程 如下一條交互形式的如下一條交互形式的SQL語(yǔ)句:語(yǔ)句: DROP TABLEStudent; 嵌入到嵌入到C程序中,應(yīng)寫作:程序中,應(yīng)寫作: EXEC SQL DROP TABLEStudent; 嵌入嵌入SQL語(yǔ)句根據(jù)其作用的不同,可分為可執(zhí)行語(yǔ)語(yǔ)句根據(jù)其作用的不同,可分為可執(zhí)行語(yǔ)句和說(shuō)明性語(yǔ)句兩類??蓤?zhí)行語(yǔ)句又分為數(shù)據(jù)定義、數(shù)句和說(shuō)明性語(yǔ)句兩類。可執(zhí)行語(yǔ)句又分為數(shù)據(jù)定義、數(shù)據(jù)控制、數(shù)據(jù)操縱三種。據(jù)控制、數(shù)據(jù)操縱三種。 在宿主程序中,任何允許出現(xiàn)可執(zhí)行的高級(jí)語(yǔ)言語(yǔ)在宿主程序中,任何允許出現(xiàn)可執(zhí)行的高級(jí)語(yǔ)言語(yǔ)句的地方,都
5、可以寫可執(zhí)行句的地方,都可以寫可執(zhí)行SQL語(yǔ)句;任何允許出現(xiàn)說(shuō)語(yǔ)句;任何允許出現(xiàn)說(shuō)明性高級(jí)語(yǔ)言語(yǔ)句的地方,都可以寫說(shuō)明性明性高級(jí)語(yǔ)言語(yǔ)句的地方,都可以寫說(shuō)明性SQL語(yǔ)句。語(yǔ)句。 第8章 數(shù)據(jù)庫(kù)編程 8.1.2 嵌入式嵌入式SQL語(yǔ)句與主語(yǔ)言之間的通信語(yǔ)句與主語(yǔ)言之間的通信 將將SQL嵌入到高級(jí)語(yǔ)言中混合編程,程序中會(huì)含嵌入到高級(jí)語(yǔ)言中混合編程,程序中會(huì)含有兩種不同計(jì)算模型的語(yǔ)句:有兩種不同計(jì)算模型的語(yǔ)句: 1 1) SQL語(yǔ)句,負(fù)責(zé)操縱數(shù)據(jù)庫(kù),是一種是描述語(yǔ)句,負(fù)責(zé)操縱數(shù)據(jù)庫(kù),是一種是描述性的面向集合的性的面向集合的SQL語(yǔ)句。語(yǔ)句。 2 2)高級(jí)語(yǔ)言語(yǔ)句,負(fù)責(zé)控制程序流程,是一種過(guò)高級(jí)語(yǔ)言語(yǔ)
6、句,負(fù)責(zé)控制程序流程,是一種過(guò)程性的高級(jí)語(yǔ)言語(yǔ)句。程性的高級(jí)語(yǔ)言語(yǔ)句。 它們它們之間應(yīng)該如何通信呢?之間應(yīng)該如何通信呢? 第8章 數(shù)據(jù)庫(kù)編程 數(shù)據(jù)庫(kù)工作單元與源程序工作單元之間通信主要包括:數(shù)據(jù)庫(kù)工作單元與源程序工作單元之間通信主要包括: 1 1)向主語(yǔ)言傳遞)向主語(yǔ)言傳遞SQLSQL語(yǔ)句的執(zhí)行狀態(tài)信息,使主語(yǔ)言能語(yǔ)句的執(zhí)行狀態(tài)信息,使主語(yǔ)言能夠據(jù)此控制程序流程;夠據(jù)此控制程序流程; 2 2)主語(yǔ)言向)主語(yǔ)言向SQLSQL語(yǔ)句提供參數(shù);語(yǔ)句提供參數(shù); 3 3)將)將SQLSQL語(yǔ)句查詢數(shù)據(jù)庫(kù)的結(jié)果交主語(yǔ)言進(jìn)一步處理。語(yǔ)句查詢數(shù)據(jù)庫(kù)的結(jié)果交主語(yǔ)言進(jìn)一步處理。 在嵌入式在嵌入式SQL中,向主語(yǔ)言傳
7、遞中,向主語(yǔ)言傳遞SQL執(zhí)行狀態(tài)信息主執(zhí)行狀態(tài)信息主要用要用SQL通信區(qū)(通信區(qū)(SQL Communication Area,簡(jiǎn)稱,簡(jiǎn)稱SQLCA)實(shí)現(xiàn);主語(yǔ)言向?qū)崿F(xiàn);主語(yǔ)言向SQL語(yǔ)句輸入數(shù)據(jù)主要用語(yǔ)句輸入數(shù)據(jù)主要用主變量(主變量(host variable)實(shí)現(xiàn);實(shí)現(xiàn);SQL語(yǔ)句向主語(yǔ)言輸出數(shù)據(jù)主要用語(yǔ)句向主語(yǔ)言輸出數(shù)據(jù)主要用主變量主變量和游標(biāo)(和游標(biāo)(cursor)實(shí)現(xiàn)。實(shí)現(xiàn)。 第8章 數(shù)據(jù)庫(kù)編程 一、一、SQL通信區(qū)通信區(qū) SQLCA是一個(gè)數(shù)據(jù)結(jié)構(gòu)。是一個(gè)數(shù)據(jù)結(jié)構(gòu)。1 1、SQLCA的用途的用途1)語(yǔ)句執(zhí)行后,系統(tǒng)要反饋給應(yīng)用程序若干信息。)語(yǔ)句執(zhí)行后,系統(tǒng)要反饋給應(yīng)用程序若干信息。
8、 描述系統(tǒng)當(dāng)前工作狀態(tài)描述系統(tǒng)當(dāng)前工作狀態(tài) 描述運(yùn)行環(huán)境描述運(yùn)行環(huán)境2)這些信息將送到)這些信息將送到SQLCA中。中。3)應(yīng)用程序從)應(yīng)用程序從SQLCA中取出這些狀態(tài)信息,據(jù)此決定中取出這些狀態(tài)信息,據(jù)此決定接下來(lái)執(zhí)行的語(yǔ)句。接下來(lái)執(zhí)行的語(yǔ)句。第8章 數(shù)據(jù)庫(kù)編程 2 2、SQLCA使用方法使用方法(1)定義)定義SQLCA 用用EXEC SQL INCLUDE SQLCA定義定義(2)使用)使用SQLCA SQLCA中有一個(gè)存放每次執(zhí)行中有一個(gè)存放每次執(zhí)行SQL語(yǔ)句后返回代語(yǔ)句后返回代碼的變量碼的變量SQLCODE。 應(yīng)用程序每執(zhí)行完一條應(yīng)用程序每執(zhí)行完一條SQL 語(yǔ)句之后都應(yīng)該測(cè)試語(yǔ)句之
9、后都應(yīng)該測(cè)試一下一下SQLCODE的值,以了解該的值,以了解該SQL語(yǔ)句執(zhí)行情況語(yǔ)句執(zhí)行情況并做相應(yīng)處理。并做相應(yīng)處理。 如果如果SQLCODE等于預(yù)定義的常量等于預(yù)定義的常量SUCCESS,則,則表示表示SQL語(yǔ)句成功,否則表示出錯(cuò)。語(yǔ)句成功,否則表示出錯(cuò)。第8章 數(shù)據(jù)庫(kù)編程 例如在執(zhí)行刪除語(yǔ)句例如在執(zhí)行刪除語(yǔ)句DELETE后,根據(jù)不同的執(zhí)后,根據(jù)不同的執(zhí)行情況,行情況,SQLCA中有下列不同的信息:中有下列不同的信息: 違反數(shù)據(jù)保護(hù)規(guī)則,操作拒絕違反數(shù)據(jù)保護(hù)規(guī)則,操作拒絕 沒(méi)有滿足條件的行,一行也沒(méi)有刪除沒(méi)有滿足條件的行,一行也沒(méi)有刪除 成功刪除,并有刪除的行數(shù)(成功刪除,并有刪除的行數(shù)(
10、SQLCODE=SUCCESS) 無(wú)條件刪除警告信息無(wú)條件刪除警告信息 由于各種原因,執(zhí)行出錯(cuò)由于各種原因,執(zhí)行出錯(cuò) 第8章 數(shù)據(jù)庫(kù)編程 二、主變量二、主變量 1 1、主變量、主變量 嵌入式嵌入式SQL語(yǔ)句中可以使用主語(yǔ)言的程序變量來(lái)輸入語(yǔ)句中可以使用主語(yǔ)言的程序變量來(lái)輸入或輸出數(shù)據(jù)?;蜉敵鰯?shù)據(jù)。SQL語(yǔ)句中使用的主語(yǔ)言程序變量簡(jiǎn)稱為主語(yǔ)句中使用的主語(yǔ)言程序變量簡(jiǎn)稱為主變量(變量(Host Variable) 。2 2、主變量的類型、主變量的類型 1 1)輸入主變量,由應(yīng)用程序?qū)ζ滟x值,輸入主變量,由應(yīng)用程序?qū)ζ滟x值,SQL語(yǔ)句引用;語(yǔ)句引用; 2 2)輸出主變量,由)輸出主變量,由SQL語(yǔ)句
11、對(duì)其賦值或設(shè)置狀態(tài)信息,語(yǔ)句對(duì)其賦值或設(shè)置狀態(tài)信息,返回給應(yīng)用程序。返回給應(yīng)用程序。 利用輸入主變量,可指定向數(shù)據(jù)庫(kù)中插入數(shù)據(jù),可利用輸入主變量,可指定向數(shù)據(jù)庫(kù)中插入數(shù)據(jù),可將數(shù)據(jù)庫(kù)中的數(shù)據(jù)修改為指定值等。利用輸出主變量,我將數(shù)據(jù)庫(kù)中的數(shù)據(jù)修改為指定值等。利用輸出主變量,我們可以得到們可以得到SQL語(yǔ)句的結(jié)果數(shù)據(jù)和狀態(tài)。語(yǔ)句的結(jié)果數(shù)據(jù)和狀態(tài)。第8章 數(shù)據(jù)庫(kù)編程 3 3、指示變量、指示變量 一個(gè)主變量可以附帶一個(gè)任選的指示變量(一個(gè)主變量可以附帶一個(gè)任選的指示變量(Indicator Variable)。)。 指示變量是一個(gè)整型變量,用來(lái)指示變量是一個(gè)整型變量,用來(lái)“指示指示”所指主變量所指主變
12、量的值或條件。的值或條件。 輸入輸入主變量可以利用指示變量賦空值,輸出主變量可主變量可以利用指示變量賦空值,輸出主變量可以利用指示變量檢測(cè)出是否空值,值是否被截?cái)?。以利用指示變量檢測(cè)出是否空值,值是否被截?cái)唷5?章 數(shù)據(jù)庫(kù)編程 4 4、在、在SQLSQL語(yǔ)句中使用主變量和指示變量的方法語(yǔ)句中使用主變量和指示變量的方法(1 1)說(shuō)明主變量和指示變量)說(shuō)明主變量和指示變量 所有主變量和指示變量必須在所有主變量和指示變量必須在SQL語(yǔ)句語(yǔ)句BEGIN DECLARE SECTION與與END DECLARE SECTION之間進(jìn)行說(shuō)明。之間進(jìn)行說(shuō)明。BEGIN DECLARE SECTION. .
13、(說(shuō)明主變量和指示變量說(shuō)明主變量和指示變量).END DECLARE SECTION第8章 數(shù)據(jù)庫(kù)編程 (2 2)使用主變量)使用主變量 說(shuō)明之后的主變量可以在說(shuō)明之后的主變量可以在SQL語(yǔ)句中任何一個(gè)能語(yǔ)句中任何一個(gè)能夠使用表達(dá)式的地方出現(xiàn)。為了與數(shù)據(jù)庫(kù)對(duì)象名(表夠使用表達(dá)式的地方出現(xiàn)。為了與數(shù)據(jù)庫(kù)對(duì)象名(表名、視圖名、列名等)區(qū)別,名、視圖名、列名等)區(qū)別,SQL語(yǔ)句中的主變量名語(yǔ)句中的主變量名前要加冒號(hào)(前要加冒號(hào)(:)作為標(biāo)志。)作為標(biāo)志。(3 3)使用指示變量)使用指示變量 SQL語(yǔ)句中的指示變量前也必須加冒號(hào)標(biāo)志,并語(yǔ)句中的指示變量前也必須加冒號(hào)標(biāo)志,并且要緊跟在所指主變量之后。且
14、要緊跟在所指主變量之后。5 5、在、在SQLSQL語(yǔ)句之外使用主變量和指示變量的方法語(yǔ)句之外使用主變量和指示變量的方法 可以直接引用,不必加冒號(hào)??梢灾苯右?,不必加冒號(hào)。第8章 數(shù)據(jù)庫(kù)編程 三、游標(biāo)三、游標(biāo) 1 1、為什么要使用游標(biāo)?、為什么要使用游標(biāo)? SQL語(yǔ)言與主語(yǔ)言具有不同數(shù)據(jù)處理方式。語(yǔ)言與主語(yǔ)言具有不同數(shù)據(jù)處理方式。 SQL語(yǔ)言是面向集合的,一條語(yǔ)言是面向集合的,一條SQL語(yǔ)句原則上可以語(yǔ)句原則上可以產(chǎn)生或處理多條記錄。產(chǎn)生或處理多條記錄。 而主語(yǔ)言是面向記錄的,一組主變量一次只能存放而主語(yǔ)言是面向記錄的,一組主變量一次只能存放一條記錄。一條記錄。 所以僅使用主變量并不能完全滿足
15、所以僅使用主變量并不能完全滿足SQL語(yǔ)句向應(yīng)用語(yǔ)句向應(yīng)用程序輸出數(shù)據(jù)的要求,為此嵌入式程序輸出數(shù)據(jù)的要求,為此嵌入式SQL引入了游標(biāo)的概引入了游標(biāo)的概念,用游標(biāo)來(lái)協(xié)調(diào)這兩種不同的處理方式。念,用游標(biāo)來(lái)協(xié)調(diào)這兩種不同的處理方式。第8章 數(shù)據(jù)庫(kù)編程 2、游標(biāo)、游標(biāo) 游標(biāo)游標(biāo)是系統(tǒng)為用戶開設(shè)的一個(gè)數(shù)據(jù)緩沖區(qū),存放是系統(tǒng)為用戶開設(shè)的一個(gè)數(shù)據(jù)緩沖區(qū),存放SQL語(yǔ)句的執(zhí)行結(jié)果。語(yǔ)句的執(zhí)行結(jié)果。 每個(gè)每個(gè)游標(biāo)區(qū)都有一個(gè)名字。游標(biāo)區(qū)都有一個(gè)名字。 用戶用戶可以用可以用SQL語(yǔ)句逐一從游標(biāo)中獲取記錄,并賦語(yǔ)句逐一從游標(biāo)中獲取記錄,并賦給主變量,交由主語(yǔ)言進(jìn)一步處理。給主變量,交由主語(yǔ)言進(jìn)一步處理。第8章 數(shù)據(jù)庫(kù)
16、編程 四、建立和關(guān)閉數(shù)據(jù)庫(kù)連接四、建立和關(guān)閉數(shù)據(jù)庫(kù)連接 嵌入式嵌入式SQL程序要訪問(wèn)數(shù)據(jù)庫(kù)必須先連接數(shù)據(jù)庫(kù)。程序要訪問(wèn)數(shù)據(jù)庫(kù)必須先連接數(shù)據(jù)庫(kù)。RDBMS根據(jù)用戶信息對(duì)連接請(qǐng)求進(jìn)行合法性驗(yàn)證,只有根據(jù)用戶信息對(duì)連接請(qǐng)求進(jìn)行合法性驗(yàn)證,只有通過(guò)了身份驗(yàn)證,才能建立一個(gè)可用的合法連接。通過(guò)了身份驗(yàn)證,才能建立一個(gè)可用的合法連接。1、建立數(shù)據(jù)庫(kù)連接、建立數(shù)據(jù)庫(kù)連接EXEC SQL CONNECT TO target AS connection-name USER user-name; target是要連接的數(shù)據(jù)庫(kù)服務(wù)器,可以是常見的服務(wù)是要連接的數(shù)據(jù)庫(kù)服務(wù)器,可以是常見的服務(wù)器標(biāo)識(shí)串,如器標(biāo)識(shí)串,如:
17、 ,或者是包,或者是包含服務(wù)器標(biāo)識(shí)的含服務(wù)器標(biāo)識(shí)的SQL串常量,也可以是串常量,也可以是DEFAULT。 connect-name是可選的連接名,必須是一個(gè)有效的標(biāo)是可選的連接名,必須是一個(gè)有效的標(biāo)識(shí)符,在整個(gè)程序內(nèi)只有一個(gè)連接時(shí)可不指定連接名識(shí)符,在整個(gè)程序內(nèi)只有一個(gè)連接時(shí)可不指定連接名第8章 數(shù)據(jù)庫(kù)編程 2、關(guān)閉數(shù)據(jù)庫(kù)連接、關(guān)閉數(shù)據(jù)庫(kù)連接 EXEC SQL DISCONNECT connection;3、程序運(yùn)行過(guò)程中可以修改當(dāng)前連接、程序運(yùn)行過(guò)程中可以修改當(dāng)前連接 EXEC SQL SET CONNECTION connection-name | DEFAULT;第8章 數(shù)據(jù)庫(kù)編程 五、
18、程序?qū)嵗濉⒊绦驅(qū)嵗?依次檢查某系的學(xué)生記錄,交互式更新某些學(xué)生年齡。依次檢查某系的學(xué)生記錄,交互式更新某些學(xué)生年齡。EXEC SQL BEGIN DEC LARE SECTION; /*主變量說(shuō)明開始*/ char deptname64;char HSno64;char HSname64; char HSsex64;int HSage;intNEWAGE;EXEC SQL END DECLARE SECTION; /*主變量說(shuō)明結(jié)束*/long SQLCODE;EXEC SQL INCLUDE sqlca; /*定義SQL通信區(qū)*/第8章 數(shù)據(jù)庫(kù)編程 int main(void) /*C
19、語(yǔ)言主程序開始*/ int count = 0; char yn; /*變量yn代表yes或no*/ printf(Please choose the department name(CS/MA/IS): ); scanf(%s, deptname); /*為主變量deptname賦值*/ EXEC SQL CONNECT TO TESTlocalhost:54321 USER SYSTEM /MANAGER; /*連接數(shù)據(jù)庫(kù)TEST*/ EXEC SQL DECLARE SX CURSOR FOR /*定義游標(biāo)*/ SELECT Sno, Sname, Ssex, Sage /*SX對(duì)應(yīng)語(yǔ)句
20、的執(zhí)行結(jié)果*/ FROM Student WHERE SDept = :deptname; EXEC SQL OPEN SX; /*打開游標(biāo)SX便指向查詢結(jié)果的第一行*/第8章 數(shù)據(jù)庫(kù)編程 for ( ; ; ) /*用循環(huán)結(jié)構(gòu)逐條處理結(jié)果集中的記錄*/ EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex,:HSage; /*推進(jìn)游標(biāo),將當(dāng)前數(shù)據(jù)放入主變量*/ if (sqlca.sqlcode != 0) /* sqlcode != 0,表示操作不成功*/ break; /*利用SQLCA中的狀態(tài)信息決定何時(shí)退出循環(huán)*/ if(count+ = 0)
21、/*如果是第一行的話,先打出行頭*/ printf(n%-10s %-20s %-10s %-10sn, Sno, Sname, Ssex, Sage); printf(%-10s %-20s %-10s %-10dn, HSno, HSname, HSsex, HSage); /*打印查詢結(jié)果*/ printf(UPDATE AGE(y/n)?); /*詢問(wèn)用戶是否更新該學(xué)生的年齡*/ do scanf(%c,&yn); while(yn != N & yn != n & yn != Y & yn != y);第8章 數(shù)據(jù)庫(kù)編程 if (yn = y | yn
22、 = Y) /*如果選擇更新操作*/printf(INPUT NEW AGE:);scanf(%d,&NEWAGE); /*用戶輸入新年齡到主變量中*/EXEC SQL UPDATE Student /*嵌入式SQL*/SET Sage = :NEWAGEWHERE CURRENT OF SX ; /*對(duì)當(dāng)前游標(biāo)指向的學(xué)生年齡進(jìn)行更新*/ EXEC SQL CLOSE SX; /*關(guān)閉游標(biāo)SX不再和查詢結(jié)果對(duì)應(yīng)*/EXEC SQL COMMIT WORK; /*提交更新*/EXEC SQL DISCONNECT TEST; /*斷開數(shù)據(jù)庫(kù)連接*/第8章 數(shù)據(jù)庫(kù)編程 例例2為了能夠更好地
23、理解上面的概念,下面給出帶有嵌入為了能夠更好地理解上面的概念,下面給出帶有嵌入式式SQL的一小段的一小段C程序。程序。EXEC SQL INCLUDE SQLCA; 定義定義SQL通信區(qū)通信區(qū)EXEC SQL BEGIN DECLARE SECTION; 說(shuō)明主變量說(shuō)明主變量CHAR title_id(7);CHAR title(81);INT royalty;EXEC SQL END DECLARE SECTION;main() EXEC SQL DECLARE C1 CURSOR FOR 定義游標(biāo)定義游標(biāo) SELECT tit_id, tit, roy FROM titles; EXEC
24、SQL OPEN C1; 打開游標(biāo)打開游標(biāo) 第8章 數(shù)據(jù)庫(kù)編程 for(;) EXEC SQL FETCH C1 INTO :title_id, :title, :royalty; if (sqlca.sqlcode SUCCESS) break; printf(Title ID: %s, Royalty: %d, :title_id, :royalty); printf(Title: %s, :title);EXEC SQL CLOSE C1; 關(guān)閉游標(biāo)關(guān)閉游標(biāo) 第8章 數(shù)據(jù)庫(kù)編程 8.1.3 不用游標(biāo)的不用游標(biāo)的SQL語(yǔ)句語(yǔ)句 不用游標(biāo)的不用游標(biāo)的SQL語(yǔ)句有:語(yǔ)句有: 說(shuō)明性語(yǔ)句說(shuō)明性語(yǔ)
25、句 數(shù)據(jù)定義語(yǔ)句數(shù)據(jù)定義語(yǔ)句 數(shù)據(jù)控制語(yǔ)句數(shù)據(jù)控制語(yǔ)句 查詢結(jié)果為單記錄的查詢結(jié)果為單記錄的SELECT語(yǔ)句語(yǔ)句 非非CURRENT形式的形式的UPDATE語(yǔ)句語(yǔ)句 非非CURRENT形式的形式的DELETE語(yǔ)句語(yǔ)句 INSERT語(yǔ)句語(yǔ)句第8章 數(shù)據(jù)庫(kù)編程 所有的說(shuō)明性語(yǔ)句及數(shù)據(jù)定義與控制語(yǔ)句都不需要所有的說(shuō)明性語(yǔ)句及數(shù)據(jù)定義與控制語(yǔ)句都不需要使用游標(biāo)。它們是嵌入式使用游標(biāo)。它們是嵌入式SQL中最簡(jiǎn)單的一類語(yǔ)句,不中最簡(jiǎn)單的一類語(yǔ)句,不需要返回結(jié)果數(shù)據(jù),也不需要使用主變量。在主語(yǔ)言中需要返回結(jié)果數(shù)據(jù),也不需要使用主變量。在主語(yǔ)言中嵌入說(shuō)明性語(yǔ)句及數(shù)據(jù)定義與控制語(yǔ)句,只要給語(yǔ)句加嵌入說(shuō)明性語(yǔ)句及
26、數(shù)據(jù)定義與控制語(yǔ)句,只要給語(yǔ)句加上前綴上前綴EXEC SQL和語(yǔ)句結(jié)束符即可。和語(yǔ)句結(jié)束符即可。 INSERT語(yǔ)句也不需要使用游標(biāo),但通常需要使用語(yǔ)句也不需要使用游標(biāo),但通常需要使用主變量。主變量。 SELECT語(yǔ)句、語(yǔ)句、UPDATE語(yǔ)句、語(yǔ)句、DELETE語(yǔ)句則復(fù)語(yǔ)句則復(fù)雜些。雜些。第8章 數(shù)據(jù)庫(kù)編程 一、說(shuō)明性語(yǔ)句一、說(shuō)明性語(yǔ)句 交互式交互式SQL中沒(méi)有說(shuō)明性語(yǔ)句,說(shuō)明性語(yǔ)句是專為中沒(méi)有說(shuō)明性語(yǔ)句,說(shuō)明性語(yǔ)句是專為在嵌入式在嵌入式SQL中說(shuō)明主變量等而設(shè)置的,主要有兩條語(yǔ)中說(shuō)明主變量等而設(shè)置的,主要有兩條語(yǔ)句:句: EXEC SQL BEGIN DECLARE SECTION; 和和 E
27、XEC SQL END DECLARE SECTION; 兩條語(yǔ)句必須配對(duì)出現(xiàn),相當(dāng)于一個(gè)括號(hào),兩條語(yǔ)兩條語(yǔ)句必須配對(duì)出現(xiàn),相當(dāng)于一個(gè)括號(hào),兩條語(yǔ)句中間是主變量的說(shuō)明。句中間是主變量的說(shuō)明。 第8章 數(shù)據(jù)庫(kù)編程 二、數(shù)據(jù)定義語(yǔ)句二、數(shù)據(jù)定義語(yǔ)句 例:例: 建立一個(gè)建立一個(gè)“學(xué)生學(xué)生”表表StudentEXEC SQL CREATE TABLE Student(Sno CHAR(5) NOT NULL UNIQUE,Sname CHAR(20),Ssex CHAR(1),Sage INT,Sdept CHAR(15); 數(shù)據(jù)定義語(yǔ)句中不允許使用主變量。例如下列語(yǔ)句數(shù)據(jù)定義語(yǔ)句中不允許使用主變量。
28、例如下列語(yǔ)句是錯(cuò)誤的:是錯(cuò)誤的: EXEC SQL DROP TABLE :table_name; 第8章 數(shù)據(jù)庫(kù)編程 三、數(shù)據(jù)控制語(yǔ)句三、數(shù)據(jù)控制語(yǔ)句 例:把查詢例:把查詢Student表權(quán)限授給用戶表權(quán)限授給用戶U1EXEC SQL GRANT SELECT ON TABLE Student TO U1; 四、查詢結(jié)果為單記錄的四、查詢結(jié)果為單記錄的SELECT語(yǔ)句語(yǔ)句 在嵌入式在嵌入式SQL中,查詢結(jié)果為單記錄的中,查詢結(jié)果為單記錄的SELECT語(yǔ)句語(yǔ)句需用需用INTO子句指定查詢結(jié)果的存放地點(diǎn)。語(yǔ)句的格式為:子句指定查詢結(jié)果的存放地點(diǎn)。語(yǔ)句的格式為:EXEC SQL SELECT AL
29、L|DISTINCT ,. INTO ,. FROM , . WHERE GROUP BY HAVING ORDER BY ASC|DESC;第8章 數(shù)據(jù)庫(kù)編程 該語(yǔ)句對(duì)交互式該語(yǔ)句對(duì)交互式SELECT語(yǔ)句的擴(kuò)充就是多了一個(gè)語(yǔ)句的擴(kuò)充就是多了一個(gè)INTO子句,把從數(shù)據(jù)庫(kù)中找到的符合條件的記錄,放到子句,把從數(shù)據(jù)庫(kù)中找到的符合條件的記錄,放到INTO子句指出的主變量中去。使用該語(yǔ)句需要注意:子句指出的主變量中去。使用該語(yǔ)句需要注意: (1) INTO子句、子句、WHERE子句的條件表達(dá)式、子句的條件表達(dá)式、HAVING短語(yǔ)的的條件表達(dá)式中均可以使用主變量,但短語(yǔ)的的條件表達(dá)式中均可以使用主變量,
30、但這些主變量必須事先加以說(shuō)明,并且引用時(shí)前面要加上這些主變量必須事先加以說(shuō)明,并且引用時(shí)前面要加上冒號(hào)。冒號(hào)。 (2)如果數(shù)據(jù)庫(kù)中沒(méi)有滿足條件的記錄,即查詢結(jié)果)如果數(shù)據(jù)庫(kù)中沒(méi)有滿足條件的記錄,即查詢結(jié)果為空,則為空,則DBMS將將SQLCODE的值置為的值置為100。 (3)如果查詢結(jié)果實(shí)際上并不是單條記錄,而是多條)如果查詢結(jié)果實(shí)際上并不是單條記錄,而是多條記錄,則程序出錯(cuò),記錄,則程序出錯(cuò),DBMS會(huì)在會(huì)在SQLCA中返回錯(cuò)誤信息。中返回錯(cuò)誤信息。第8章 數(shù)據(jù)庫(kù)編程 (4)查詢返回的記錄中,可能某些列值為空值)查詢返回的記錄中,可能某些列值為空值NULL。 如果如果INTO子句中主變量后
31、面跟有指示變量,則當(dāng)查子句中主變量后面跟有指示變量,則當(dāng)查詢得出的某個(gè)數(shù)據(jù)項(xiàng)為空值時(shí),系統(tǒng)會(huì)自動(dòng)將相應(yīng)主變?cè)兊贸龅哪硞€(gè)數(shù)據(jù)項(xiàng)為空值時(shí),系統(tǒng)會(huì)自動(dòng)將相應(yīng)主變量后面的指示變量置為負(fù)值,但不向該主變量執(zhí)行賦值量后面的指示變量置為負(fù)值,但不向該主變量執(zhí)行賦值操作,即主變量值仍保持執(zhí)行操作,即主變量值仍保持執(zhí)行SQL語(yǔ)句之前的值。所以語(yǔ)句之前的值。所以當(dāng)發(fā)現(xiàn)指示變量值為負(fù)值時(shí),不管主變量為何值,均應(yīng)當(dāng)發(fā)現(xiàn)指示變量值為負(fù)值時(shí),不管主變量為何值,均應(yīng)認(rèn)為主變量值為認(rèn)為主變量值為NULL。 指示變量只能用于指示變量只能用于INTO子句中,并且也必須事先加子句中,并且也必須事先加以說(shuō)明,引用時(shí)前面要加上冒號(hào)。以
32、說(shuō)明,引用時(shí)前面要加上冒號(hào)。第8章 數(shù)據(jù)庫(kù)編程 例:根據(jù)學(xué)生號(hào)碼查詢學(xué)生信息。假設(shè)已將要查詢的學(xué)生例:根據(jù)學(xué)生號(hào)碼查詢學(xué)生信息。假設(shè)已將要查詢的學(xué)生的學(xué)號(hào)賦給了主變量的學(xué)號(hào)賦給了主變量givensno EXEC SQL SELECT Sno, Sname, Ssex, Sage, Sdept INTO :Hsno, :Hname, :Hsex, :Hage, :Hdept FROM Student WHERE Sno=:givensno; 上面的上面的SELECT語(yǔ)句中語(yǔ)句中Hsno, Hname, Hsex, Hage, Hdept和和givensno均是主變量,并均已在前面的程序中說(shuō)均是主
33、變量,并均已在前面的程序中說(shuō)明過(guò)了。明過(guò)了。第8章 數(shù)據(jù)庫(kù)編程 例:例: 查詢某個(gè)學(xué)生選修某門課程的成績(jī)。假設(shè)已將要查詢查詢某個(gè)學(xué)生選修某門課程的成績(jī)。假設(shè)已將要查詢的學(xué)生的學(xué)號(hào)賦給了主變量的學(xué)生的學(xué)號(hào)賦給了主變量givensno,將課程號(hào)賦給了,將課程號(hào)賦給了主變量主變量givencno EXEC SQL SELECT Sno, Cno, Grade INTO :Hsno, :Hcno, :Hgrade : Gradeid FROM SC WHERE Sno=:givensno AND Cno=:givencno; 由于學(xué)生選修一門課后有可能沒(méi)有參加考試,即可由于學(xué)生選修一門課后有可能沒(méi)有參
34、加考試,即可為空值,所以在為空值,所以在INTO子句中加了指示變量子句中加了指示變量Gradeid,用,用于指示主變量于指示主變量Hgrade是否為空值。指示變量也需事先說(shuō)是否為空值。指示變量也需事先說(shuō)明。執(zhí)行此語(yǔ)句后,如果明。執(zhí)行此語(yǔ)句后,如果Gradeid小于小于0,則不論,則不論Hgrade為何值,均認(rèn)為該學(xué)生成績(jī)?yōu)榭罩?。為何值,均認(rèn)為該學(xué)生成績(jī)?yōu)榭罩怠?第8章 數(shù)據(jù)庫(kù)編程 五、非五、非CURRENT形式的形式的UPDATE語(yǔ)句語(yǔ)句 在在UPDATE語(yǔ)句中,語(yǔ)句中,SET子句和子句和WHERE子句中均可子句中均可以使用主變量,其中以使用主變量,其中SET子句中還可以使用指示變量。子句中還
35、可以使用指示變量。例:將全體學(xué)生例:將全體學(xué)生1號(hào)課程的考試成績(jī)?cè)黾尤舾煞?。假設(shè)增加號(hào)課程的考試成績(jī)?cè)黾尤舾煞帧<僭O(shè)增加的分?jǐn)?shù)已賦給主變量的分?jǐn)?shù)已賦給主變量Raise EXEC SQL UPDATE SC SET Grade=Grade+:Raise WHERE Cno=1; 該操作實(shí)際上是一個(gè)集合操作,該操作實(shí)際上是一個(gè)集合操作,DBMS會(huì)修改所有學(xué)會(huì)修改所有學(xué)生的生的1號(hào)課程的號(hào)課程的Grade屬性列。屬性列。第8章 數(shù)據(jù)庫(kù)編程 例例6:修改某個(gè)學(xué)生:修改某個(gè)學(xué)生1號(hào)課程的成績(jī)。假設(shè)該學(xué)生的學(xué)號(hào)已賦給號(hào)課程的成績(jī)。假設(shè)該學(xué)生的學(xué)號(hào)已賦給主變量主變量givensno,修改后的成績(jī)已賦給主變量
36、,修改后的成績(jī)已賦給主變量newgrade EXEC SQL UPDATE SC SET Grade=:newgrade WHERE Sno=:givensno;例例7 :將計(jì)算機(jī)系全體學(xué)生年齡置:將計(jì)算機(jī)系全體學(xué)生年齡置NULL值值 Sageid=-1; EXEC SQL UPDATE Student SET Sage=:Raise:Sageid WHERE Sdept=CS; 將指示變量將指示變量Sageid賦一個(gè)負(fù)值后,無(wú)論主變量賦一個(gè)負(fù)值后,無(wú)論主變量Raise為為何值,何值,DBMS都會(huì)將都會(huì)將CS系所有記錄的年齡屬性置空值。它系所有記錄的年齡屬性置空值。它等價(jià)于:等價(jià)于: EXEC
37、 SQL UPDATE Student SET Sage=NULL WHERE Sdept=CS; 第8章 數(shù)據(jù)庫(kù)編程 六、非六、非CURRENT形式的形式的DELETE語(yǔ)句語(yǔ)句 DELETE語(yǔ)句的語(yǔ)句的WHERE子句中可以使用主變量指子句中可以使用主變量指定刪除條件。定刪除條件。例:某個(gè)學(xué)生退學(xué)了,現(xiàn)要將有關(guān)他的所有選課記錄刪除例:某個(gè)學(xué)生退學(xué)了,現(xiàn)要將有關(guān)他的所有選課記錄刪除掉。假設(shè)該學(xué)生的姓名已賦給主變量掉。假設(shè)該學(xué)生的姓名已賦給主變量stdnameEXEC SQL DELETE FROM SC WHERE Sno= (SELECT Sno FROM Student WHERE Snam
38、e=:stdname);第8章 數(shù)據(jù)庫(kù)編程 另一種等價(jià)實(shí)現(xiàn)方法為:另一種等價(jià)實(shí)現(xiàn)方法為: EXEC SQL DELETE FROM SC WHERE :stdname= (SELECT Sname FROM Student WHERE Studnet.Sno=SC.sno); 顯然第一種方法更直接,從而也更高效些。顯然第一種方法更直接,從而也更高效些。 如果該學(xué)生選修了多門課程,執(zhí)行上面的語(yǔ)句時(shí),如果該學(xué)生選修了多門課程,執(zhí)行上面的語(yǔ)句時(shí),DBMS會(huì)自動(dòng)執(zhí)行集合操作,即把他選修的所有課程都會(huì)自動(dòng)執(zhí)行集合操作,即把他選修的所有課程都刪除掉。刪除掉。 第8章 數(shù)據(jù)庫(kù)編程 七、七、INSERT語(yǔ)句語(yǔ)
39、句 INSERT語(yǔ)句的語(yǔ)句的VALUES子句中可以使用主變量和指子句中可以使用主變量和指示變量。示變量。例:某個(gè)學(xué)生新選修了某門課程,將有關(guān)記錄插入例:某個(gè)學(xué)生新選修了某門課程,將有關(guān)記錄插入SC表中。表中。假設(shè)學(xué)生的學(xué)號(hào)已賦給主變量假設(shè)學(xué)生的學(xué)號(hào)已賦給主變量stdno,課程號(hào)已賦給主變,課程號(hào)已賦給主變量量couno。 gradeid=-1; EXEC SQL INSERT INTO SC(Sno, Cno, Grade) VALUES(:stdno, :couno, :gr:gradeid); 由于該學(xué)生剛選修課程,尚未考試,因此成績(jī)列為由于該學(xué)生剛選修課程,尚未考試,因此成績(jī)列為空。所以
40、本例中用指示變量指示相應(yīng)的主變量為空值???。所以本例中用指示變量指示相應(yīng)的主變量為空值。第8章 數(shù)據(jù)庫(kù)編程 8.1.4 使用游標(biāo)的使用游標(biāo)的SQL語(yǔ)句語(yǔ)句 必須使用游標(biāo)的必須使用游標(biāo)的SQL語(yǔ)句有:語(yǔ)句有: 查詢結(jié)果為多條記錄的查詢結(jié)果為多條記錄的SELECT語(yǔ)句語(yǔ)句 CURRENT形式的形式的UPDATE語(yǔ)句語(yǔ)句 CURRENT形式的形式的DELETE語(yǔ)句語(yǔ)句 一、查詢結(jié)果為多條記錄的一、查詢結(jié)果為多條記錄的SELECT語(yǔ)句語(yǔ)句 一般情況下,一般情況下,SELECT語(yǔ)句查詢結(jié)果都是多條記錄,語(yǔ)句查詢結(jié)果都是多條記錄,而高級(jí)語(yǔ)言一次只能處理一條記錄,因此需要以游標(biāo)機(jī)而高級(jí)語(yǔ)言一次只能處理一條記
41、錄,因此需要以游標(biāo)機(jī)制作為橋梁,將多條記錄一次一條送至宿主程序處理,制作為橋梁,將多條記錄一次一條送至宿主程序處理,從而把對(duì)集合的操作轉(zhuǎn)換為對(duì)單個(gè)記錄的處理。從而把對(duì)集合的操作轉(zhuǎn)換為對(duì)單個(gè)記錄的處理。第8章 數(shù)據(jù)庫(kù)編程 使用游標(biāo)的步驟為:使用游標(biāo)的步驟為: (1)說(shuō)明游標(biāo)。)說(shuō)明游標(biāo)。 EXEC SQL DECLARE CURSOR FOR ; (2)打開游標(biāo)。)打開游標(biāo)。 EXEC SQL OPEN ; (3)推進(jìn)游標(biāo)指針并取當(dāng)前記錄。)推進(jìn)游標(biāo)指針并取當(dāng)前記錄。EXEC SQL FETCH INTO ,.; (4)關(guān)閉游標(biāo)。)關(guān)閉游標(biāo)。EXEC SQL CLOSE ;第8章 數(shù)據(jù)庫(kù)編程 例
42、:查詢某個(gè)系全體學(xué)生的信息。要查詢的系名由用戶在例:查詢某個(gè)系全體學(xué)生的信息。要查詢的系名由用戶在程序運(yùn)行過(guò)程中指定,放在主變量程序運(yùn)行過(guò)程中指定,放在主變量deptname中中 EXEC SQL BEGIN DECLARE SECTION; /* 說(shuō)明主變量說(shuō)明主變量*/EXEC SQL END DECLARE SECTION;gets(deptname); /* 為主變量為主變量deptname賦值賦值 */EXEC SQL DECLARE SX CURSOR FOR SELECT Sno, Sname, Ssex, Sage FROM Student WHERE SDept=:deptn
43、ame; /* 說(shuō)明游標(biāo)說(shuō)明游標(biāo) */EXEC SQL OPEN SX /* 打開游標(biāo)打開游標(biāo) */第8章 數(shù)據(jù)庫(kù)編程 WHILE(1) EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage; /* 取值并送主變量取值并送主變量 */if (sqlca.sqlcode SUCCESS) break; /* 若處理完畢或出現(xiàn)若處理完畢或出現(xiàn)SQL錯(cuò)誤,則退出循環(huán)錯(cuò)誤,則退出循環(huán) */ ./* 由主語(yǔ)言語(yǔ)句進(jìn)行進(jìn)一步處理由主語(yǔ)言語(yǔ)句進(jìn)行進(jìn)一步處理 */; EXEC SQL CLOSE SX; /* 關(guān)閉游標(biāo)關(guān)閉游標(biāo) */第8章 數(shù)據(jù)庫(kù)編程 二、
44、二、CURRENT形式的形式的UPDATE語(yǔ)句和語(yǔ)句和DELETE語(yǔ)句語(yǔ)句 非非CURRENT形式的形式的UPDATE語(yǔ)句和語(yǔ)句和DELETE語(yǔ)句都是語(yǔ)句都是集合操作,一次修改或刪除所有滿足條件的記錄。如果只集合操作,一次修改或刪除所有滿足條件的記錄。如果只想修改或刪除其中某個(gè)記錄,則需要用帶游標(biāo)的想修改或刪除其中某個(gè)記錄,則需要用帶游標(biāo)的SELECT語(yǔ)句查出所有滿足條件的記錄,從中進(jìn)一步找出要修改或語(yǔ)句查出所有滿足條件的記錄,從中進(jìn)一步找出要修改或刪除的記錄,然后修改或刪除之。具體地說(shuō)就是:刪除的記錄,然后修改或刪除之。具體地說(shuō)就是: (1) 用用DECLARE語(yǔ)句說(shuō)明游標(biāo)。如果是為語(yǔ)句說(shuō)明
45、游標(biāo)。如果是為CURRENT形式的形式的UPDATE語(yǔ)句作準(zhǔn)備,則語(yǔ)句作準(zhǔn)備,則SELECT語(yǔ)句中要用語(yǔ)句中要用FOR UPDATE OF 子句指明將來(lái)檢索出的數(shù)據(jù)在指定列是可修改的。如果是子句指明將來(lái)檢索出的數(shù)據(jù)在指定列是可修改的。如果是為為CURRENT形式的形式的DELETE語(yǔ)句作準(zhǔn)備,則不必使用上語(yǔ)句作準(zhǔn)備,則不必使用上述子句。述子句。第8章 數(shù)據(jù)庫(kù)編程 (2)用)用OPEN語(yǔ)句打開游標(biāo),把所有滿足查詢條件的記錄從語(yǔ)句打開游標(biāo),把所有滿足查詢條件的記錄從指定表取到緩沖區(qū)中。指定表取到緩沖區(qū)中。(3) 用用FETCH語(yǔ)句推進(jìn)游標(biāo)指針,并把當(dāng)前記錄從緩沖區(qū)語(yǔ)句推進(jìn)游標(biāo)指針,并把當(dāng)前記錄從緩
46、沖區(qū)中取出來(lái)送至主變量。中取出來(lái)送至主變量。(4)檢查該記錄是否是要修改或刪除。若是,則用)檢查該記錄是否是要修改或刪除。若是,則用UPDATE語(yǔ)句或語(yǔ)句或DELETE語(yǔ)句修改或刪除該記錄。這時(shí)語(yǔ)句修改或刪除該記錄。這時(shí)UPDATE語(yǔ)語(yǔ)句和句和DELETE語(yǔ)句中要用語(yǔ)句中要用 WHERE CURRENT OF 子句,表示修改或刪除的是該游標(biāo)中最近一次取出的記錄,子句,表示修改或刪除的是該游標(biāo)中最近一次取出的記錄,即游標(biāo)指針指向的記錄。即游標(biāo)指針指向的記錄。 第第3和和4步通常用在一個(gè)循環(huán)結(jié)構(gòu)中,通過(guò)循環(huán)執(zhí)行步通常用在一個(gè)循環(huán)結(jié)構(gòu)中,通過(guò)循環(huán)執(zhí)行FETCH語(yǔ)句,逐條取出結(jié)果集中的行進(jìn)行判斷和處理
47、。語(yǔ)句,逐條取出結(jié)果集中的行進(jìn)行判斷和處理。 (5)處理完畢用)處理完畢用CLOSE語(yǔ)句關(guān)閉游標(biāo),釋放結(jié)果集占用的語(yǔ)句關(guān)閉游標(biāo),釋放結(jié)果集占用的緩沖區(qū)和其他資源。緩沖區(qū)和其他資源。第8章 數(shù)據(jù)庫(kù)編程 例:查詢某個(gè)系全體學(xué)生的信息(要查詢的系名由主變量例:查詢某個(gè)系全體學(xué)生的信息(要查詢的系名由主變量deptname指定),然后根據(jù)用戶的要求修改刪除其中某些指定),然后根據(jù)用戶的要求修改刪除其中某些記錄。記錄。EXEC SQL BEGIN DECLARE SECTION; /* 說(shuō)明主變量說(shuō)明主變量 deptname,HSno,HSname,HSsex,HSage等等*/EXEC SQL END
48、 DECLARE SECTION;gets(deptname); EXEC SQL DECLARE SX CURSOR FOR SELECT Sno, Sname, Ssex, Sage FROM Student WHERE SDept=:deptname; EXEC SQL OPEN SX第8章 數(shù)據(jù)庫(kù)編程 WHILE(1) EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage; if (sqlca.sqlcode SUCCESS) break; printf(%s, %s, %s, %d, Sno, Sname, Ssex, Sage)
49、; printf(DELETE ? ); scanf(%c,&yn); if (yn=y or yn=Y) EXEC SQL DELETE FROM Student WHERE CURRENT OF SX; /* 刪除當(dāng)前記錄刪除當(dāng)前記錄 */ ;EXEC SQL CLOSE SX; 第8章 數(shù)據(jù)庫(kù)編程 8.1.5 動(dòng)態(tài)動(dòng)態(tài)SQL 靜態(tài)嵌入式靜態(tài)嵌入式SQL 靜態(tài)嵌入式靜態(tài)嵌入式SQL語(yǔ)句能夠滿足一般要求語(yǔ)句能夠滿足一般要求 無(wú)法滿足要到執(zhí)行時(shí)才能夠確定要提交的無(wú)法滿足要到執(zhí)行時(shí)才能夠確定要提交的SQL語(yǔ)句語(yǔ)句 動(dòng)態(tài)嵌入式動(dòng)態(tài)嵌入式SQL 允許在程序運(yùn)行過(guò)程中臨時(shí)允許在程序運(yùn)行過(guò)程中臨
50、時(shí)“組裝組裝”SQL語(yǔ)句語(yǔ)句 支持動(dòng)態(tài)組裝支持動(dòng)態(tài)組裝SQL語(yǔ)句和動(dòng)態(tài)參數(shù)兩種形式語(yǔ)句和動(dòng)態(tài)參數(shù)兩種形式第8章 數(shù)據(jù)庫(kù)編程 一、使用一、使用SQL語(yǔ)句主變量語(yǔ)句主變量 程序主變量包含的內(nèi)容是程序主變量包含的內(nèi)容是SQL語(yǔ)句的內(nèi)容,而不是原語(yǔ)句的內(nèi)容,而不是原來(lái)保存數(shù)據(jù)的輸入或輸出變量。來(lái)保存數(shù)據(jù)的輸入或輸出變量。 SQL語(yǔ)句主變量在程序執(zhí)行期間可以設(shè)定不同的語(yǔ)句主變量在程序執(zhí)行期間可以設(shè)定不同的SQL語(yǔ)句,然后立即執(zhí)行語(yǔ)句,然后立即執(zhí)行 。例:創(chuàng)建基本表例:創(chuàng)建基本表TESTEXEC SQL BEGIN DECLARE SECTION;const char *stmt = CREATE TAB
51、LE test(a int); /* SQL語(yǔ)句主變量語(yǔ)句主變量 */EXEC SQL END DECLARE SECTION;. .EXEC SQL EXECUTE IMMEDIATE :stmt; /* 執(zhí)行語(yǔ)句執(zhí)行語(yǔ)句 */第8章 數(shù)據(jù)庫(kù)編程 二、動(dòng)態(tài)參數(shù)二、動(dòng)態(tài)參數(shù) 動(dòng)態(tài)參數(shù)是動(dòng)態(tài)參數(shù)是SQL語(yǔ)句中的可變?cè)?,使用參?shù)符號(hào)語(yǔ)句中的可變?cè)?,使用參?shù)符號(hào)(?)表表示該位置的數(shù)據(jù)在運(yùn)行時(shí)設(shè)定。示該位置的數(shù)據(jù)在運(yùn)行時(shí)設(shè)定。 和主變量不同,動(dòng)態(tài)參數(shù)的輸入不是編譯時(shí)完成綁定,和主變量不同,動(dòng)態(tài)參數(shù)的輸入不是編譯時(shí)完成綁定,而是通過(guò)而是通過(guò) (prepare)語(yǔ)句準(zhǔn)備主變量和執(zhí)行語(yǔ)句準(zhǔn)備主變量和執(zhí)
52、行(execute)時(shí)綁定數(shù)時(shí)綁定數(shù)據(jù)或主變量來(lái)完成。據(jù)或主變量來(lái)完成。 使用動(dòng)態(tài)參數(shù)的步驟:使用動(dòng)態(tài)參數(shù)的步驟:1.聲明聲明SQL語(yǔ)句主變量。語(yǔ)句主變量。2.準(zhǔn)備準(zhǔn)備SQL語(yǔ)句語(yǔ)句(PREPARE)。EXEC SQL PREPARE FROM ;3.執(zhí)行準(zhǔn)備好的語(yǔ)句執(zhí)行準(zhǔn)備好的語(yǔ)句(EXECUTE)EXEC SQL EXECUTE INTO USING ;第8章 數(shù)據(jù)庫(kù)編程 例:向例:向TEST中插入元組。中插入元組。EXEC SQL BEGIN DECLARE SECTION;const char *stmt = INSERT INTO test VALUES(?); /*聲明聲明SQL主
53、變量主變量 */EXEC SQL END DECLARE SECTION;. .EXEC SQL PREPARE mystmt FROM :stmt; /* 準(zhǔn)備語(yǔ)句準(zhǔn)備語(yǔ)句 */. .EXEC SQL EXECUTE mystmt USING 100; /* 執(zhí)行語(yǔ)句執(zhí)行語(yǔ)句 */EXEC SQL EXECUTE mystmt USING 200; /* 執(zhí)行語(yǔ)句執(zhí)行語(yǔ)句 */第8章 數(shù)據(jù)庫(kù)編程 8.2.1 PL/SQL的塊結(jié)構(gòu)的塊結(jié)構(gòu) PL/SQL是編寫數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程的一種過(guò)程語(yǔ)言。它結(jié)合了SQL的數(shù)據(jù)操作能力和過(guò)程化語(yǔ)言的流程控制能力,是SQL的過(guò)程化發(fā)展。 PL/SQL程序的基本結(jié)構(gòu)是
54、塊。所有的PL/SQL程序都是由塊構(gòu)成。塊之間可以互相嵌套 每個(gè)塊完成一個(gè)邏輯操作 8.2 存儲(chǔ)過(guò)程存儲(chǔ)過(guò)程第8章 數(shù)據(jù)庫(kù)編程 PL/SOL塊的基本結(jié)構(gòu):塊的基本結(jié)構(gòu): 1、定義部分、定義部分 DECLARE -變量、常量、游標(biāo)、異常等 n定義的變量、常量等只能在該基本塊中使用n當(dāng)基本塊執(zhí)行結(jié)束時(shí),定義就不再存在2、執(zhí)行部分、執(zhí)行部分 BEGIN -SQL語(yǔ)句、PL/SQL的流程控制語(yǔ)句 EXCEPTION -異常處理部分 END;第8章 數(shù)據(jù)庫(kù)編程 8.2.2 變量常量的定義變量常量的定義1. PL/SQL中定義變量的語(yǔ)法形式是中定義變量的語(yǔ)法形式是: 變量名 數(shù)據(jù)類型 NOT NULL:=
55、初值表達(dá)式或 變量名 數(shù)據(jù)類型 NOT NULL初值表達(dá)式2. 常量的定義類似于變量的定義常量的定義類似于變量的定義: 常量名 數(shù)據(jù)類型 CONSTANT :=常量表達(dá)式 常量必須要給一個(gè)值,并且該值在存在期間或常量的作用域內(nèi)不能改變。如果試圖修改它,PL/SQL將返回一個(gè)異常。3. 賦值語(yǔ)句賦值語(yǔ)句 變量名稱:=表達(dá)式第8章 數(shù)據(jù)庫(kù)編程 8.2.3 控制結(jié)構(gòu)控制結(jié)構(gòu) 一、一、 條件控制語(yǔ)句條件控制語(yǔ)句 IF-THEN, IF-THEN-ELSE和嵌套的和嵌套的IF語(yǔ)句語(yǔ)句 1. IF condition THEN Sequence_of_statements; END IF 2. IF co
56、ndition THEN Sequence_of_statements1; ELSE Sequence_of_statements2; END IF;3. 在THEN和ELSE子句中還可以再包括IF語(yǔ)句,即IF語(yǔ)句可以嵌套。第8章 數(shù)據(jù)庫(kù)編程 二、循環(huán)控制語(yǔ)句二、循環(huán)控制語(yǔ)句 LOOP, WHILE-LOOP和和FOR-LOOP 1.最簡(jiǎn)單的循環(huán)語(yǔ)句最簡(jiǎn)單的循環(huán)語(yǔ)句LOOP LOOP Sequence_of_statements; END LOOP; 多數(shù)數(shù)據(jù)庫(kù)服務(wù)器的PL/SQL都提供EXIT、BREAK或LEAVE等循環(huán)結(jié)束語(yǔ)句,保證LOOP語(yǔ)句塊能夠結(jié)束。第8章 數(shù)據(jù)庫(kù)編程 2. WHI
57、LE-LOOP WHILE condition LOOP Sequence_of_statements;END LOOP;n每次執(zhí)行循環(huán)體語(yǔ)句之前,首先對(duì)條件進(jìn)行求值n如果條件為真,則執(zhí)行循環(huán)體內(nèi)的語(yǔ)句序列。n如果條件為假,則跳過(guò)循環(huán)并把控制傳遞給下一個(gè)語(yǔ)句 3. FOR-LOOP FOR count IN REVERSEbound1 bound2 LOOP Sequence_of_statements;END LOOP;第8章 數(shù)據(jù)庫(kù)編程 三、錯(cuò)誤處理三、錯(cuò)誤處理 如果PL/SQL在執(zhí)行時(shí)出現(xiàn)異常,則應(yīng)該讓程序在產(chǎn)生異常的語(yǔ)句處停下來(lái),根據(jù)異常的類型去執(zhí)行異常處理語(yǔ)句。 SQL標(biāo)準(zhǔn)對(duì)數(shù)據(jù)庫(kù)服
58、務(wù)器提供什么樣的異常處理做出了建議,要求PL/SQL管理器提供完善的異常處理機(jī)制 。第8章 數(shù)據(jù)庫(kù)編程 8.2.4 存儲(chǔ)過(guò)程存儲(chǔ)過(guò)程PL/SQL塊類型: 命名塊:編譯后保存在數(shù)據(jù)庫(kù)中,可以被反復(fù)調(diào)用,運(yùn)行速度較快。存儲(chǔ)過(guò)程和函數(shù)是命名塊。 匿名塊:每次執(zhí)行時(shí)都要進(jìn)行編譯,它不能被存儲(chǔ)到數(shù)據(jù)庫(kù)中,也不能在其他的PL/SQL塊中調(diào)用。第8章 數(shù)據(jù)庫(kù)編程 存儲(chǔ)過(guò)程:由PL/SQL語(yǔ)句書寫的過(guò)程,經(jīng)編譯和優(yōu)化后存儲(chǔ)在數(shù)據(jù)庫(kù)服務(wù)器中,使用時(shí)只要調(diào)用即可。 一、存儲(chǔ)過(guò)程的優(yōu)點(diǎn)一、存儲(chǔ)過(guò)程的優(yōu)點(diǎn)1. 運(yùn)行效率高2. 降低了客戶機(jī)和服務(wù)器之間的通信量3. 方便實(shí)施企業(yè)規(guī)則第8章 數(shù)據(jù)庫(kù)編程 二、二、 存儲(chǔ)過(guò)程
59、的用戶接口存儲(chǔ)過(guò)程的用戶接口 用戶可通過(guò)下面的用戶可通過(guò)下面的SQL語(yǔ)句創(chuàng)建、重命名、執(zhí)行和刪語(yǔ)句創(chuàng)建、重命名、執(zhí)行和刪除存儲(chǔ)過(guò)程。除存儲(chǔ)過(guò)程。1. 創(chuàng)建存儲(chǔ)過(guò)程創(chuàng)建存儲(chǔ)過(guò)程CREATE Procedure 過(guò)程名(參數(shù)1,參數(shù)2,.) AS;n過(guò)程名:數(shù)據(jù)庫(kù)服務(wù)器合法的對(duì)象標(biāo)識(shí)n參數(shù)列表:用名字來(lái)標(biāo)識(shí)調(diào)用時(shí)給出的參數(shù)值,必須指定值的數(shù)據(jù)類型。參數(shù)也可以定義輸入?yún)?shù)、輸出參數(shù)或輸入/輸出參數(shù)。默認(rèn)為輸入?yún)?shù)。n過(guò)程體:是一個(gè)。包括聲明部分和可執(zhí)行語(yǔ)句部分 第8章 數(shù)據(jù)庫(kù)編程 例: 利用存儲(chǔ)過(guò)程來(lái)實(shí)現(xiàn)下面的應(yīng)用: 從一個(gè)賬戶轉(zhuǎn)指定數(shù)額的款項(xiàng)到另一個(gè)賬戶中。CREATE PROCEDURE TRA
60、NSFER(inAccount INT, outAccount INT, amount FLOAT) AS DECLAREtotalDeposit FLOAT;BEGIN /* 檢查轉(zhuǎn)出賬戶的余額 */ SELECT total INTO totalDeposit FROM ACCOUNT WHERE ACCOUNTNUM=outAccount; IF totalDeposit IS NULL THEN /* 賬戶不存在或賬戶中沒(méi)有存款 */ ROLLBACK; RETURN; END IF; 第8章 數(shù)據(jù)庫(kù)編程 IF totalDeposit amount THEN /* 賬戶賬戶存款不足 */ ROLLBACK; RETURN;EN
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 提供材料合同范本
- 租賃合同范本押金
- 5風(fēng)兒輕輕吹(教學(xué)設(shè)計(jì))-2023-2024學(xué)年道德與法治一年級(jí)下冊(cè)統(tǒng)編版
- 6 綜合與實(shí)踐(教學(xué)設(shè)計(jì))-2024-2025學(xué)年一年級(jí)上冊(cè)數(shù)學(xué)北師大版
- 煤炭訂貨合同范本
- 2024-2025學(xué)年高中英語(yǔ)選修課趣味英語(yǔ)教學(xué)設(shè)計(jì)
- 3《我們班 他們班》第二課時(shí)(教學(xué)設(shè)計(jì))-部編版道德與法治四年級(jí)上冊(cè)
- 9 這些是大家的(教學(xué)設(shè)計(jì))-2024-2025學(xué)年統(tǒng)編版道德與法治二年級(jí)上冊(cè)
- 噴泉采購(gòu)合同范本
- 擔(dān)保公司融資合同范本
- 《服裝品牌策劃》課件
- 個(gè)人應(yīng)聘簡(jiǎn)歷電工
- 高血壓的用藥指導(dǎo)任務(wù)三高血壓的藥物治療講解
- 近五年陜西中考數(shù)學(xué)真題及答案2024
- 美國(guó)藥典-USP-561-植物源性物質(zhì)
- 施工安全管理培訓(xùn)資料
- 0-3歲嬰幼兒基礎(chǔ)護(hù)理知到智慧樹章節(jié)測(cè)試課后答案2024年秋杭州師范大學(xué)
- 掛靠免責(zé)協(xié)議書范本
- 2024-2030年中國(guó)新媒體市場(chǎng)前景規(guī)模及發(fā)展趨勢(shì)分析報(bào)告
- Python金融數(shù)據(jù)分析與挖掘(微課版) 教案全套 黃恒秋
- 中建10t龍門吊安拆安全專項(xiàng)施工方案
評(píng)論
0/150
提交評(píng)論