不用游標(biāo)的嵌入式SQL語(yǔ)句應(yīng)用技術(shù) 轉(zhuǎn)自廈門大學(xué)的一個(gè)網(wǎng)上課件
Posted on 2008-09-10 10:30 Prayer 閱讀(601) 評(píng)論(0) 編輯 收藏 引用 所屬分類: 數(shù)據(jù)庫(kù),SQL 、C/C++廈門大學(xué)的一個(gè)課件 備查
http://www.cs.xmu.edu.cn/education/fine_courses/database/%BE%AB%C6%B7%BF%CE%B3%CC%BD%A8%C9%E8%C4%DA%C8%DD/3_%CD%F8%C2%E7%B0%E6cai/content/index.htm
3. 不用游標(biāo)的嵌入式SQL語(yǔ)句應(yīng)用技術(shù)
所謂不用游標(biāo)的SQL語(yǔ)句,是指一般不需要返回結(jié)果數(shù)據(jù),也不需要使用主變量的語(yǔ)句。它們是嵌入式SQL中最簡(jiǎn)單的一類語(yǔ)句。有以下幾種:
· 說(shuō)明性語(yǔ)句
· 數(shù)據(jù)定義語(yǔ)句
· 數(shù)據(jù)控制語(yǔ)句
· 查詢結(jié)果為單記錄的SELECT語(yǔ)句
· 非CURRENT形式的UPDATE語(yǔ)句
· 非CURRENT形式的DELETE語(yǔ)句
· INSERT語(yǔ)句
其中:
*) 所有的說(shuō)明性語(yǔ)句、數(shù)據(jù)定義與控制語(yǔ)句都不需要使用游標(biāo),在主語(yǔ)言中嵌入說(shuō)明性語(yǔ)句、數(shù)據(jù)定義與控制語(yǔ)句,只要給語(yǔ)句加上前綴EXEC SQL和語(yǔ)句結(jié)束符即可。
*) INSERT語(yǔ)句也不需要使用游標(biāo),但通常需要使用主變量。
*) SELECT語(yǔ)句、UPDATE語(yǔ)句、DELETE語(yǔ)句則更復(fù)雜些。
以下分別討論常見的幾種使用方法:
一、說(shuō)明性語(yǔ)句
交互式SQL中沒(méi)有說(shuō)明性語(yǔ)句,這里的說(shuō)明性語(yǔ)句是專為在嵌入式SQL中說(shuō)明主變量等而設(shè)置的,一對(duì)由兩條語(yǔ)句組成:
EXEC SQL BEGIN DECLARE SECTION;
<變量定義語(yǔ)句>
EXEC SQL END DECLARE SECTION;
兩條語(yǔ)句必須配對(duì)出現(xiàn),相當(dāng)于一個(gè)括號(hào),兩條語(yǔ)句中間是主變量、指示變量的說(shuō)明。
二、數(shù)據(jù)定義語(yǔ)句
例1 建立一個(gè)“學(xué)生”表Student
EXEC 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ǔ)句是錯(cuò)誤的:
EXEC SQL DROP TABLE :table_name;
三、數(shù)據(jù)控制語(yǔ)句
例2 把查詢Student表權(quán)限授給用戶U1
EXEC SQL GRANT SELECT ON TABLE Student TO U1;
四、查詢結(jié)果為單記錄的SELECT語(yǔ)句
在嵌入式SQL中,查詢結(jié)果為單記錄的SELECT語(yǔ)句需要用INTO子句指定查詢結(jié)果的存放地點(diǎn)。該語(yǔ)句的一般格式為:
EXEC SQL SELECT [ALL|DISTINCT] <目標(biāo)列表達(dá)式>[,<目標(biāo)列表達(dá)式>]...
INTO <主變量>[<指示變量>][,<主變量>[<指示變量>]]...
FROM <表名或視圖名>[,<表名或視圖名>] ...
[WHERE <條件表達(dá)式>]
[GROUP BY <列名1> [HAVING <條件表達(dá)式>]]
[ORDER BY <列名2> [ASC|DESC]];
說(shuō)明:
該語(yǔ)句對(duì)交互式SELECT語(yǔ)句的擴(kuò)充就是多了一個(gè)INTO子句,把從數(shù)據(jù)庫(kù)中找到的符合條件的記錄,放到INTO子句指出的主變量中去。其他子句的含義不變。使用該語(yǔ)句需要注意以下幾點(diǎn):
*) INTO子句、WHERE子句的條件表達(dá)式、HAVING短語(yǔ)的的條件表達(dá)式中均可以使用主變量,但這些主變量必須事先加以說(shuō)明,并且引用時(shí)前面要加上冒號(hào)。
*) 查詢返回的記錄中,可能某些列值為空值NULL,則如下處理:如果INTO子句中主變量后面跟有指示變量,則當(dāng)查詢得出的某個(gè)數(shù)據(jù)項(xiàng)為空值時(shí),系統(tǒng)會(huì)自動(dòng)將相應(yīng)主變量后面的指示變量置為負(fù)值,但不向該主變量執(zhí)行賦值操作,即主變量值仍保持執(zhí)行SQL語(yǔ)句之前的值。所以當(dāng)發(fā)現(xiàn)指示變量值為負(fù)值時(shí),不管主變量為何值,均應(yīng)認(rèn)為主變量值為NULL。指示變量只能用于INTO子句中,并且也必須事先加以說(shuō)明,引用時(shí)前面要加上冒號(hào)。
*) 如果數(shù)據(jù)庫(kù)中沒(méi)有滿足條件的記錄,即查詢結(jié)果為空,則DBMS將SQLCODE的值置為100。
*) 如果查詢結(jié)果實(shí)際上并不是單條記錄,而是多條記錄,則程序出錯(cuò),DBMS會(huì)在SQLCA中返回錯(cuò)誤信息。
例3 根據(jù)學(xué)生號(hào)碼查詢學(xué)生信息。假設(shè)已將要查詢的學(xué)生的學(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ǔ)句中Hsno, Hname, Hsex, Hage, Hdept和givensno均是主變量,并均已在前面的程序中說(shuō)明過(guò)了。
例4 查詢某個(gè)學(xué)生選修某門課程的成績(jī)。假設(shè)已將要查詢的學(xué)生的學(xué)號(hào)賦給了主變量givensno,將課程號(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)有參加考試,也就是說(shuō)其成績(jī)?yōu)榭罩担晕覀冊(cè)谠摾齀NTO子句中加了指示變量Gradeid,用于指示主變量Hgrade是否為空值。指示變量也需要和所有主變量一起在前面程序中事先說(shuō)明。執(zhí)行此語(yǔ)句后,如果Gradeid小于0,則不論Hgrade為何值,均認(rèn)為該學(xué)生成績(jī)?yōu)榭罩怠?/p>
雖然對(duì)于僅返回一行結(jié)果數(shù)據(jù)的SELECT語(yǔ)句可以不使用游標(biāo),但從應(yīng)用程序獨(dú)立性角度考慮,最好還是使用游標(biāo)。因?yàn)槿绻院髷?shù)據(jù)庫(kù)改變了,該SELECT語(yǔ)句可能會(huì)返回多行數(shù)據(jù),這時(shí)不使用游標(biāo)就會(huì)出錯(cuò)。
五、非CURRENT形式的UPDATE語(yǔ)句
非CURRENT形式是指特殊情況下的應(yīng)用。在這種情況下的嵌入式UPDATE語(yǔ)句中,SET子句和WHERE子句都可以使用主變量,其中SET子句中還可以使用指示變量。以下分別用幾個(gè)例子說(shuō)明它們的應(yīng)用技術(shù):
例5 將全體學(xué)生1號(hào)課程的考試成績(jī)?cè)黾尤舾煞帧<僭O(shè)增加的分?jǐn)?shù)已賦給主變量Raise
EXEC SQL UPDATE SC
SET Grade=Grade+:Raise
WHERE Cno='1';
該操作實(shí)際上是一個(gè)集合操作,DBMS會(huì)修改所有學(xué)生的1號(hào)課程的Grade屬性列。
例6 修改某個(gè)學(xué)生1號(hào)課程的成績(jī)。假設(shè)該學(xué)生的學(xué)號(hào)已賦給主變量givensno,修改后的成績(jī)已賦給主變量newgrade
EXEC SQL UPDATE SC
SET Grade=:newgrade
WHERE Sno=:givensno;
例7 將計(jì)算機(jī)系全體學(xué)生年齡置NULL值
Sageid=-1;
EXEC SQL UPDATE Student
SET Sage=:Raise:Sageid
WHERE Sdept='CS';
將指示變量Sageid賦一個(gè)負(fù)值后,無(wú)論主變量Raise為何值,DBMS都會(huì)將CS系所有記錄的年齡屬性置空值。它等價(jià)于:
EXEC SQL UPDATE Student
SET Sage=NULL
WHERE Sdept='CS';
六、非CURRENT形式的DELETE語(yǔ)句
與上同理,DELETE語(yǔ)句的WHERE子句中可以使用主變量指定刪除條件。
例8 某個(gè)學(xué)生退學(xué)了,現(xiàn)要將有關(guān)他的所有選課記錄刪除掉。假設(shè)該學(xué)生的姓名已賦給主變量stdname
EXEC SQL DELETE
FROM SC
WHERE Sno=
(SELECT Sno
FROM Student
WHERE Sname=:stdname);
另一種等價(jià)實(shí)現(xiàn)方法為:
EXEC SQL DELETE
FROM SC
WHERE :stdname=
(SELECT Sname
FROM Student
WHERE Studnet.Sno=SC.sno);
顯然第一種方法更直接,從而也更高效些。
如果該學(xué)生選修了多門課程,執(zhí)行上面的語(yǔ)句時(shí),DBMS會(huì)自動(dòng)執(zhí)行集合操作,即把他選修的所有課程都刪除掉。
七、INSERT語(yǔ)句
INSERT語(yǔ)句的VALUES子句中可以使用主變量和指示變量。
例9 某個(gè)學(xué)生新選修了某門課程,將有關(guān)記錄插入SC表中。假設(shè)學(xué)生的學(xué)號(hào)已賦給主變量stdno,課程號(hào)已賦給主變量couno。
gradeid=-1;
EXEC SQL INSERT
INTO SC(Sno, Cno, Grade)
VALUES(:stdno, :couno, :gr:gradeid);
由于該學(xué)生剛選修課程,尚未考試,因此成績(jī)列為空。所以本例中用指示變量指示相應(yīng)的主變量為空值。
廈門大學(xué)計(jì)算機(jī)科學(xué)系 薛永生


