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