數(shù)據(jù)庫原理及應(yīng)用_第1頁
數(shù)據(jù)庫原理及應(yīng)用_第2頁
數(shù)據(jù)庫原理及應(yīng)用_第3頁
數(shù)據(jù)庫原理及應(yīng)用_第4頁
數(shù)據(jù)庫原理及應(yīng)用_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

數(shù)據(jù)庫原理及應(yīng)用第1頁,共29頁,2023年,2月20日,星期六嵌入式SQL是指在程序內(nèi)執(zhí)行的SQL語句,它強調(diào)這些SQL語句是“嵌入”在編程語言的常規(guī)語句中的。Java中標準的嵌入式SQL稱為SQLJ,可以在ORACLE、INFORMIX、DB2UDB中使用,也可以通過JDBC在Java中使用,JDBC是標準Java的一部分,用來連接任何數(shù)據(jù)庫。我們將重點放在C語言編寫的嵌入式SQL程序。在本章中,我們將會碰到兩種數(shù)據(jù)庫系統(tǒng)的差別,即oracle和db2udb第2頁,共29頁,2023年,2月20日,星期六5.1C語言中嵌入SQL的介紹關(guān)鍵詞execsql聲明SQL語句嵌入到宿主語言源文件中。例如:execsqlselectcount(*)into:host_varfromcustomers;注:1、execsql可以擴展到該文件的多行。2、在嵌入式SQL中使用宿主變量時必須加(:)例:假如字符串變量cust_id在C程序中被賦值為“c001”第3頁,共29頁,2023年,2月20日,星期六execsqlselectcname,discnt

into:

cust_name,:cust_discntfromcustomerswherecid=:cust_id則檢索到顧客編號為c001的顧客的名字和折扣率,并將它們分別賦值給變量cust_name,cust_discnt。

當然,要在嵌入式SQL中使用這些宿主變量,必須先聲明它們,包括對預(yù)編譯程序的聲明。第4頁,共29頁,2023年,2月20日,星期六

execsqlbegindeclaresection;charcust_id[5]=“c001”;charcust_name[14];floatcust_discnt;

execsqlenddeclaresection;這三個變量的聲明是標準的C語言中的聲明,出現(xiàn)在begindeclare和enddeclare語句之間,這是預(yù)編譯程序和C語言程序都能理解的相同的格式。嵌入式SQL中使用的宿主變量必須能被數(shù)據(jù)庫系統(tǒng)識別。第5頁,共29頁,2023年,2月20日,星期六

在SQL中建立和釋放數(shù)據(jù)庫連接:考慮怎樣與數(shù)據(jù)庫管理系統(tǒng)建立數(shù)據(jù)庫連接。在FullSQL-99中連接到SQL數(shù)據(jù)庫的語法:

execsqlconnecttotarget-server[asconnect-name][userusername]或execsqlconnecttodefaulttarget-server是目標數(shù)據(jù)庫名,connect-name是對這次該數(shù)據(jù)庫連接的一個名字,以后當再次使用是,可以直接引用它;username是該數(shù)據(jù)庫的一個合法用戶名。connecttodefault是默認數(shù)據(jù)庫的連接。第6頁,共29頁,2023年,2月20日,星期六由于不同平臺在用戶識別、權(quán)限要求方面的可變性,connect語句并不是EntrySQL-92和CoreSQL-99的一部分。在ORACLE和DB2UDB中,字符串常量通常不能直接作為connect語句的參數(shù),我們需要首先聲明:execsqlbegindeclaresection;

charuser_name[10],user_pwd[10];

execsqlenddeclaresection;設(shè)口令“1234”,我們對上述變量初始化:

strcpy(user_name,”cap”);strcpy(user_pwd,”1234”);第7頁,共29頁,2023年,2月20日,星期六那么在DB2中嵌入式SQL的Connect語句為:execsqlconnectto

cap

:user_name

using:user_pwd;

在ORACLE中嵌入式SQL的Connect語句為:

execsqlconnect:user_name

identifiedby:

user_pwd;簡單的斷開連接:

execsqldisconnectcurrent/connect_name;注意:

在斷開連接之前,必須對成功的事務(wù)提交確認,或是對失敗的事務(wù)回滾以撤消已做的工作,否則直接斷開連接會失敗。第8頁,共29頁,2023年,2月20日,星期六對成功的任務(wù)結(jié)束為:execsqlcommitwork;execsqldisconnectcurrent;對失敗的任務(wù)結(jié)束則為:

execsqlrollbackwork;execsqldisconnectcurrent;在ORACLE中可以使用

execsqlcommitrelease;

或execsqlrollbackrelease;第9頁,共29頁,2023年,2月20日,星期六例5.1.1實現(xiàn)一個嵌入式SQL程序,要求程序不斷提示用戶輸入一個顧客的cid,顯示該顧客的名字和折扣,當用戶輸入一個空字符串則程序終止。程序頭如下:#include<stdio.h>#include”prompt.h”/*headerfordbssqlcastructure*/execsqlincludesqlca;charcid_prompt[]=“pleaseentercustomerid”;第10頁,共29頁,2023年,2月20日,星期六程序主體代碼:intmain(){execsqlbegindeclaresection;charcust_id[5],cust_name[14];floatcust_discnt;charuser_name[20],user_pwd[20];execsqlenddeclaresection;execsqlwheneversqlerrorgotoreport_error;execsqlwhenevernotfoundgotonotfound;strcpy(user_name,”cap”);strcpy(user_pwd,”1234”);execsqlconnect:user_nameidentifiedby:user_pwd;第11頁,共29頁,2023年,2月20日,星期六while((prompt(cid_prompt,1,cust_id,4))>=0)

{execsqlselectcname,discntinto:cust_name,:cust_discntfromcustomerswherecid=:cust_id;execsqlcommitwork;printf(“customer’snameis%sanddiscntis%5.1f”,cust_name,cust_discnt);continue;notfound:printf(“can’tfind%s“,cust_id)}execsqlcommitrelease;return0;report_error:print_dberror();execsqlrollbackrelease;return1;}第12頁,共29頁,2023年,2月20日,星期六程序說明:

print_dberror()函數(shù)顯示數(shù)據(jù)庫系統(tǒng)的錯誤消息,如ORACLE中的“ORA-00942:tableorviewdoesnotexist”。prompt函數(shù)提示用戶交互,prompt函數(shù)也可以接受用戶輸入的多個標記,若用戶在提示行上鍵入回車,則返回結(jié)果小于0。

C語言編譯程序不能識別嵌入式execsql語句的語法,所以源程序必須先通過預(yù)編譯程序?qū)⑵滢D(zhuǎn)換成C中的正確語句。(參見附錄B.3)Whenever語句是條件處理語句,該語句使我們在遇到出錯和其他情況時,控制程序的運行。第13頁,共29頁,2023年,2月20日,星期六其格式如下:

execsqlwheneverconditionaction;例execsqlwheneversqlerrorgotoreport_error;Whenever設(shè)置了一個條件陷阱,這樣會對所有后面由execsql語句引起的對數(shù)據(jù)庫系統(tǒng)的調(diào)用自動檢查是否出錯條件,若存在這樣的出錯條件,就必須采取規(guī)定的動作。(1)條件

sqlerror

這些錯誤通常是由編程錯誤引起的。并且錯誤代碼依賴于某一特定的DBMS。notfound

執(zhí)行某條SQL語句,如insert、delete、update等,檢測是否沒有記錄受到該SQL語句的影響。第14頁,共29頁,2023年,2月20日,星期六sqlwarning

檢測不是錯誤但應(yīng)該引起注意的條件。注意:sqlwarning不是FullSQL-92的標準。(2)動作

continue

不采取任何動作,程序按正常流程

goto標號等同與C語言中的“goto標號”

stop

結(jié)束程序的運行,撤消當前的事務(wù),斷開與數(shù)據(jù)庫的連接

do函數(shù)(ORACLE)、call函數(shù)(INFORMIX)引發(fā)一個對已經(jīng)命名的C函數(shù)的調(diào)用,這一函數(shù)返回后,程序從引發(fā)該變遷的execsql語句之后繼續(xù)執(zhí)行下去。

第15頁,共29頁,2023年,2月20日,星期六注意:當遇到一條后續(xù)的whenever語句覆蓋了前面的whenever語句時,程序動作就被改變了。例5.2.1

main(){execsqlwheneversqlerrorstop;

execsqldelete*fromagentswhereaid=‘a(chǎn)03’gotos1;execsqlwheneversqlerrorcontinue;s1:execsqlupdateagentssetpercent=percent+1;…….}第16頁,共29頁,2023年,2月20日,星期六注意:在沒有whenever時,缺省動作是continue;可以通過execsqlwheneversqlerrorcontinue來重建這一缺省動作。我們在使用whenever語句時要注意避免無限循環(huán)。例:execsqlwheneversqlerrorgotohandle_error;execsqlcreatetablecustomers(cid……);

由于某個錯誤(磁盤空間不夠等)導(dǎo)致建表失敗,控制流轉(zhuǎn)入handle_errorhandle_error:

有問題嗎?execsqldropcustomers;execsqldisconnect;return–1;第17頁,共29頁,2023年,2月20日,星期六刪除表時,可能會引起無限循環(huán)。故應(yīng)改為:

handle_error:

execsqlwheneversqlerrorcontinue;execsqldropcustomers;execsqldisconnect;return–1;第18頁,共29頁,2023年,2月20日,星期六SQL通信區(qū):SQLCASQL通信區(qū),稱為SQLCA,是一個已經(jīng)被聲明過的內(nèi)存結(jié)構(gòu)(C中的結(jié)構(gòu)),它的成員變量用來在數(shù)據(jù)庫系統(tǒng)監(jiān)視器與程序之間進行信息通信。SQLCA在嵌入式的C程序中聲明,通常寫在其他的外部聲明語句前面。

execsqlincludesqlca;實際上,whenever機制的基礎(chǔ)是一個提供了更多與條件有關(guān)的信息的錯誤編碼系統(tǒng)。支持SQLCA的產(chǎn)品要填寫sqlca.sqlcode(一個與錯誤碼相關(guān)的變量)第19頁,共29頁,2023年,2月20日,星期六注意:SQL-92、SQL-99等標準支持一種新的報告錯誤的方法,SQLSTATE。在ORACLE中,必須預(yù)處理程序運行時設(shè)置MODE=ANSI才能支持。在DB2UDB中提供SQLSTATE作為SQLCA的一個成員。SQLSTATE是由一個5個字符的字符串編碼組成,前兩個字符為“類別編碼”,后3個字符為“子類編碼”。例如:“00000”代表沒有錯誤,“82100”表示“內(nèi)存溢出”,對于所有的產(chǎn)品這一編碼都是相同的。若whenever語句中采取的動作不是continue,那么要進行顯示的錯誤檢測是不行的。第20頁,共29頁,2023年,2月20日,星期六例5.2.3考慮如下代碼段:

execsqlwheneversqlerrorgotohandle_error;…execsqlcreatetablecusts(cidchar(4)notnull,cnamevarchar(13),..);if(strcmp(sqlca.sqlstate,”82100”)==0)<callproceduretohandlethiscondition>注意:雖然預(yù)處理程序在createtable之后立即設(shè)置了sqlerror檢測,但是該錯誤漸次將永遠不會執(zhí)行。為什么?如何修改?第21頁,共29頁,2023年,2月20日,星期六execsqlwheneversqlerrorgotohandle_error;…..execsqlwheneversqlerrorcontinue;execsqlcreatetablecusts(cidchar(4)notnull,cnamevarchar(13)..);if(strcmp(sqlca.sqlstate,”82100”)==0)<callproceduretohandlethiscondition>elseif(strcmp(sqlca.sqlsqlstate,”00000”)!=0)gotohandle_error;execsqlwheneversqlerrorgotohandle_error;…第22頁,共29頁,2023年,2月20日,星期六使用游標選擇多行只有當select語句保證每次最多讀一行到一個列變量的集合時,才能使用例5.1.1中的嵌入式select語句格式。我們在程序中如何對檢索到的多行進行處理呢?一次一行原則

從一條select語句中,我們總是每次查看一行,每次從記錄集中檢索一行,需要一個游標記錄當前位置。第23頁,共29頁,2023年,2月20日,星期六例如,對一個用戶交互提供的一個特定的顧客的編號cust_id,我們需要檢索出為該顧客提供定貨的代理商aid,以及每個代理商所提供給顧客的定單金額總值。

Execsqlselectaid,sum(dollars)fromorderswherecid=:cust_idgroupbyaid下面,我們?yōu)檫@段select語句聲明一個名為agent_dollars的游標。Execsql

declare

agent_dollarscursorfor

selectaid,sum(dollars)fromorderswherecid=:cust_idgroupbyaid第24頁,共29頁,2023年,2月20日,星期六注意:在游標被聲明后,它仍然不是active狀態(tài)。之后,必須激活該游標:

execsqlopenagent_dollars;

執(zhí)行程序在碰到該激活語句,向數(shù)據(jù)庫系統(tǒng)檢測器發(fā)出一個調(diào)用,以執(zhí)行該游標聲明的select語句,將查詢的結(jié)果集保存在數(shù)據(jù)庫系統(tǒng)為該游標創(chuàng)建的系統(tǒng)緩沖區(qū)中。然后,我們可以使用fetch語句從該緩沖區(qū)中檢索連續(xù)的記錄行:

execsqlfetchagent_dollarsinto:agent_id,:dollar_sum第25頁,共29頁,2023年,2月20日,星期六當一個游標所有的fetch語句都執(zhí)行之后,應(yīng)該執(zhí)行closecursor語句,關(guān)閉游標,釋放資源。注:游標中保持一個當前指針,該指針總是指向最近剛剛被檢索到的行,在隨后的提取調(diào)用中,游標的位置指針首先加1,然后這條記錄中的值被檢索到指定的宿主變量中去。例5.1.2下面給出了一個檢索多行的程序:groupbyselect語句列出了代理商的ID值,以及由這些代理商提供給某一用戶指出的顧客的定單金額總值。注:該程序是按照DB2UDB的格式第26頁,共29頁,2023年,2月20日,星期六#inclued<stdio.h>…..execsqlincludesqlca;execsqlbegindeclaresection;charcust_id[5],agent_id[4];doubledollar_sum;execsqlenddeclaresection;

intmain()

{charcid_prompt[]=“pleaseentercustomerid”;execs

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論