配色: 字号:
第7章 数据库编程基础
2022-11-05 | 阅:  转:  |  分享 
  
第7章 数据库编程基础7.1 嵌入式SQL语句 7.2 事务处理SQL语句 7.3 基本SQL语句7.4 游标的应用7.5 动态SQL语句7
.6 存储过程7.7 触发器7.8 本章小结7.9 本章习题 7.1 嵌入式SQL语句 SQL是Structured Query
Language的缩写,即结构化查询语句,关系型数据库管理系统的标准语句。PowerBuilder既支持标准SQL语句,又提供了对
嵌入式SQL语句的支持。嵌入式SQL语句进一步加强了数据库操纵的灵活性,同时也有效地解决了数据窗口未能提供的与数据库交互的有关问题
。PowerBuilder在将嵌入式SQL语句发送到具体的数据库管理系统之前,并不作任何的处理,而是由具体的数据库管理系统执行相应
的SQL语句,然后返回处理结果,最终将处理结果在PowerBuilder中显示出来。 7.1.1 SQL语句语法格式在PowerB
uilder中,嵌入式SQL语句的书写格式为:SQL语句;每条完整的SQL语句必须以分号“;”结束。SQL语句既可以写成一行,又可
以写成多行,只需要在语句结束后放上一个分号“;”即可。例如以下代码:INSERT INTO "chapter" ( "id", "
name" ) VALUES ( 7, “ 第7章 数据库编程基础 ” ) ;在嵌入式SQL语句中,可以使用合法的常量和变量。如
果使用了变量,那么必须在变量名前加上冒号“:”,例如以下代码:SELECT "chapter"."id", "chapter"."
name"INTO :id, :name FROM "chapter" ; 7.1.2 SQL语句执行检查SQL语句的执行可能成
功,也可能失败,因此良好的编程风格是在每条执行的SQL语句后检查其执行情况,然后根据执行情况给出相应的提示。在PowerBuild
er中,每执行完一条SQL语句之后,与执行该SQL语句相关联的事务对象的属性SQLCode就会返回一个数值来指示最近一条SQL语句
的执行是否成功。SQLCode属性的返回值及其意义如表7-1所示。 7.2.1 CONNECT语句CONNECT语句主要用于通过指
定的事务对象建立与数据库的连接。CONNECT语句的语法格式为:CONNECT {Using TransactionObject}
;值得一提的是,在执行该语句前,事务对象必须已经正确的设置了数据库连接的属性。通常在应用对象的Open事件中进行数据库的连接,例如
以下代码:SQLCA.DBMS = "ODBC"SQLCA.DBParm = "ConnectString=''DSN=experi
ment;UID=;PWD=''“CONNECT USING SQLCA;7.2.2 DISCONNECT语句DISCONNECT语
句主要用于断开数据库连接。执行该语句时,事务对象首先执行COMMIT语句进行事务提交,然后再断开数据库连接。DISCONNECT语
句的语法格式为:DISCONNECT {Using TransactionObject};通常在应用对象的Close事件中断开与数
据库的连接,例如以下代码:IF SQLCA.dbhandle( ) <> 0 then DISCONNECT USING SQLC
A;END IF7.2.3 COMMIT 语句COMMIT语句主要用于提交事务,完成对数据库的物理修改。COMMIT语句的执行并不
会断开同数据库的连接,但会关闭所有打开的游标和过程,然后开始一个新的事务。COMMIT语句的语法格式为:COMMIT {Using
TransactionObject};例如以下代码:IF dw_1.update( ) = 1 then COMMIT US
ING SQLCA;END IF 7.2.4 ROLLBACK语句ROLLBACK语句用于回滚事务,撤销未完成的事务。ROLLBA
CK语句的执行并不会断开同数据库的连接,但会关闭所有打开的游标和过程,然后开始一个新的事务。ROLLBACK语句的语法格式为:RO
LLBACK {Using TransactionObject};例如以下代码:IF this.update( ) = 1 the
n COMMIT USING SQLCA;ELSE ROLLBACK USING SQLCA;END IF 7.3 基本S
QL语句基本SQL语句是指对数据库中的数据表进行查询和操纵的简单SQL语句,主要包括以下四种:SELECT语句、INSERT语句D
ELETE语句和UPDATE语句。此外,数据库中还经常使用到针对Blob数据类型操作的SQL语句:SELECTBLOB和UPDAT
EBLOB。 7.3.1 SELECT语句SELECT语句主要用于检索数据库中满足一定条件的记录,其语法格式为:SELECT
FieldListINTO VariableListFROM TableListWHE
RE Criteria {Using TransactionObject}; 例7.1试设计以下程序,实现根据
输入的章节编号从章节表chapter中检索得到章节名称,程序的运行界面如图7-1所示。7.3.2 INSERT语句INSERT语句
主要用于向数据表中增加一条记录,其语法格式为:INSERT INTO TableName ( FieldName {,...}
)VALUES ( ValueOfField {,...} ) { Using TransactionObject }
; 例7.2试设计以下程序,实现把输入的章节编号和章节名称保存到章节表chapter中,程序的运行界面如图7-2所示: 7.3.3
DELETE语句DELETE语句主要用于删除满足一定条件的记录,其语法格式为:DELETE FROM TableNameWHER
E Criteria {Using TransactionObject}; 例7.3试设计以下程序,实现根据输入的章节编号从章节
表chapter中删除相应的记录信息,程序的运行界面如图7-3所示: 7.3.4 UPDATE语句UPDATE语句主要用于更新数据
表中满足一定条件的记录,其语法格式为:UPDATE TableNameSET FieldName1 = Value1 { ,
FieldName2 = Value2 { , ...}}WHERE Criteria {Using Transactio
nObject}; 例7.4试设计以下程序,实现将章节表chapter中的所有记录的章节名称更新为窗口中输入的章节名称,程序的运行
界面如图7-4所示: 7.3.5 SELECTBLOB语句SELECTBLOB语句主要用于从数据库中检索大二进制对象数据,其语法格
式为:SELECTBLOB RestOfSelectStatement {USING TransactionObject} ;例
7.5试设计以下程序,实现将实验表experiment中的指定章节编号和实验编号的实验的结果图片显示在图片框中,程序的运行界面如图
7-5所示。 7.3.6 UPDATEBLOB语句UPDATEBLOB语句主要用于更新数据库中的大二进制对象数据,其语法格式为:U
PDATEBLOB TableName SET BlobColumn = BlobVariable RestOfUpdateSta
tement {USING TransactionObject} ; 例7.6试设计以下程序,实现将实验表experiment中的
指定章节编号和实验编号的实验的结果图片更新为单行文本框中指定路径的图片。程序运行窗口如图7-5所示。 7.4 游标的应用 游标的引
入,主要是为了解决SQL语句的查询结果集为多条记录而一般程序设计语句一次只能处理一条记录的矛盾。例如SELECT查询语句得到的记录
集为多条,但是它一次只能检索得到当前的这条记录,如果要循环读取多条记录时,就需要使用游标了。游标的使用主要包括以下4个步骤,即声明
游标、打开游标、读取数据以及关闭游标。 7.4 游标的应用7.4.1 声明游标游标在被打开之前必须首先要求声明,就象自定义变量一样
遵从先声明后使用的原则。声明游标使用DECLARE语句,其语法格式为:DECLARE CursorName CURSOR FOR
SelectStatement{Using TransactionObject};7.4.2 打开游标游标在声明了之后,就可以被打
开,打开游标的过程就是执行相应的SQL语句的过程。打开游标使用OPEN语句,其语法格式为:OPEN CursorName ; 7.
4 游标的应用7.4.3 读取数据游标在打开了之后,就可以进行数据的读取。读取数据使用FETCH语句,FETCH语句将从游标的当前
位置读取一条记录,并且把每列的值保存在相应的变量中,同时游标指针自动下移一条记录。其语法格式为:FETCH CursorName
INTO VariableList; 7.4.4 关闭游标数据处理完毕之后,就可以关闭游标。关闭游标使用CLOSE语句,其语法格式
为:CLOSE CursorName ; FETCH CursorName INTO VariableList;DO WHILE
SQLCA.SQLCode = 0 … //数据处理 FETCH CursorName INTO Varia
bleList;LOOP 7.5 动态SQL语句 基本SQL语句的内容在编译时已经确定,因此难以有效处理动态生成的SQL语句,给数
据库的访问带来较大的局限性;语句的部分或者整个SQL语句在运行时才确定下来,因此它不仅能够处理程序动态生成的SQL语句,还能够处理
某些数据库管理系统所特有的SQL语句。常用的动态SQL语句主要有以下4种类型:无输入参数、无结果集;有输入参数,没有结果集;编译时
已经知道参数和结果集的列;开发程序时尚不知道参数和结果集。 7.5 动态SQL语句动态SQL语句在使用时需要涉及到动态策略区对象
(DynamicStagingArea)和动态描述区对象(DynamicDescriptionArea)。动态策略区对象主要用于存
储准备执行的动态SQL语句及其有关参数的信息,它没有可供应用程序访问的属性。PowerBuilder提供了一个名为SQLSA的动态
策略区对象类型的全局变量,可以在程序中被直接使用。动态描述区对象主要用于存储以下描述的第四种动态SQL语句的输入和输出参数。Pow
erBuilder提供了一个名为SQLDA的动态描述区对象类型的全局变量,可以在程序中被直接使用。 7.5.1第一种类型这种类型的
动态SQL语句既没有输入参数,也没有返回结果集,例如表结构的创建和删除,数据的插入和删除等等,因为没有返回值,所以不能用于SELE
CT查询。第一种动态SQL语句的语法格式为:EXECUTE IMMEDIATE SQLStatement{Using Transa
ctionObject}; 例7.7 试用第一种动态SQL语句实现例7.2中的功能,即把输入的章节编号和章节名称保存到章节表cha
pter中。 7.5.2第二种类型这种类型的动态SQL语句用于执行那些有输入参数,但没有结果集的SQL语句,其中的参数在运行时确定
。第二种动态SQL语句的语法格式主要分成两部分:① 用于准备SQL语句;② 用于执行准备好的SQL语句,如下所示:PREPARE
DynamicStagingArea FROM SQLStatement{Using TransactionObject};EXE
CUTE DynamicStagingArea USING { ParameterList } ; 例7.8 试用第二种动态SQL
语句实现例7.2中的功能,即把输入的章节编号和章节名称保存到章节表chapter中。 7.5.3第三种类型这种类型的动态SQL语句
用于处理参数个数和结果集在编译时已知的情况,它有使用游标和使用存储过程两种形式。这里只介绍使用游标的方法,使用存储过程的方法类似。
第三种动态SQL语句的语法格式为:DECLARE CursorName DYNAMIC CURSOR FOR DynamicSta
gingArea ;PREPARE DynamicStagingArea FROM SQLStatement {Using Tra
nsactionObject};OPEN DYNAMIC CursorName {Using ParameterList};FET
CH CursorName INTO VariableList ;CLOSE CursorName ;例7.9 试用第三种动态SQ
L语句设计以下程序,实现将表chapter中已经存在的记录的章节编号、章节名称查询出来,并且添加到列表框中,程序运行界面如图7-6
所示。 7.5.4第四种类型这种类型的动态SQL语句最为复杂,同时功能也最为强大,它能够处理参数和结果集在编译时依然未知的SQL语
句。与第三种动态SQL语句类似,它也有使用游标和使用存储过程两种形式。这里只介绍使用游标的方法,使用存储过程的方法类似,其语法格式
如下:DECLARE CursorName DYNAMIC CURSOR FOR DynamicStagingArea ;PREP
ARE DynamicStagingArea FROM SQLStatement {Using TransactionObject
};DESCRIBE DynamicStagingArea INTO DynamicDescriptionArea ;OPEN D
YNAMIC CursorName {Using DESCRIPTOR DynamicDescriptionArea};FETCH
CursorName {Using DESCRIPTOR DynamicDescriptionArea};CLOSE Curso
rName ; 7.5.4第四种类型在这类动态SQL语句中,最为重要的就是动态描述区SQLDA的使用,它有以下4个常用的属性:Nu
mInputs: 输入参数的个数;NumOutputs:输出参数的个数;InParmType: 输入参数类型,是个数组,其中每
个元素依次对应于SQL语句中的各个问号的类型;OutParmType:输出参数类型,是个数组,其中每个元素依次对应于一个输出参数的
类型;InParmType和OutParmType两个数组的数据类型均为枚举类型,其值可以取:TypeDate!、TypeTime
!、TypeDateTime!、TypeString!、TypeBoolean!、TypeInteger!、TypeUInt!、T
ypeLong!、TypeULong!、TypeDecimal!、TypeDouble!、TypeReal!。如果要给输入参数赋值
,可以调用SQLDA的SetDynamicParm()函数;如果要得到输出参数的值,则针对不同的类型,SQLDA提供了不同的函数进
行调用,如GetDynamicDate()、GetDynamicTime()、GetDynamicDateTime()、GetDy
namicString()和GetDynamicNumber()。 7.5.4第四种类型例7.10 试用第四种动态SQL语句设计以
下程序,实现由用户手动输入查询SQL语句,然后将查询得到的信息添加到列表框中,程序运行界面如图7-7所示。 7.6 存储过程存储过
程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过存储过程的名字并给出参数(如果该存储过程带有参数)来执行它
。存储过程分为两类:系统提供的存储过程和用户自定义存储过程。系统存储过程主要用于从系统表中获取信息。当创建一个新数据库时,一些系统
存储过程会在新数据库中被自动创建。用户自定义存储过程是由用户创建,并能完成某一特定功能,如查询用户所需的数据信息。 7.6.1 存
储过程语法格式Watcom-SQL语法格式:CREATE?PROCEDURE?[?owner.]procedure-name?(?
[?parameter,?...?]?) {?? [?RESULT?(?result-column,?...?)?] ????[?
ON?EXCEPTION?RESUME? ] ??????compound-statement ??? |?AT?location
-string ?? ?|?EXTERNAL?NAME?library-call ?? ?|?[?DYNAMIC?RESULT?S
ETS?integer-expression?] ?????[?EXTERNAL?NAME?java-call?LANGUAGE?
JAVA?] }CREATE PROCEDURE showdept( in deptname varchar(30) )RE
SULT ( lastname char(20), firstname char(20))ON EXCEPTION RESUMEB
EGIN SELECT employee.emp_lname, employee.emp_fname FROM depar
tment, employee WHERE department.dept_name = deptname AND dep
artment.dept_id = employee.dept_idEND 7.6.1 存储过程语法格式Transact-SQL格
式: CREATE?PROCEDURE?[owner.]procedure_name [?[?(?]?@parameter_nam
e? data-type?[?=?default?]?[?OUTPUT?],?...?[?)?]?]
[?WITH?RECOMPILE?]?AS?statement-list CREATE PROCEDURE showdept
@deptname varchar(30)AS SELECT employee.emp_lname, employee.e
mp_fname FROM department, employee WHERE department.dept_name
= @deptname AND department.dept_id = employee.dept_id7.6.2 存储过
程创建方法Sybase Central中创建存储过程 PowerBuilder中创建存储过程: 7.6.3 存储过程调用过程声明存
储过程:使用DECLARE子句声明数据库中的某个存储过程的逻辑名称。声明存储过程的语法如下所示:DECLARE logical_p
rocedure_name PROCEDURE FOR{@rv = } SQL_Server_procedure_name@Par
am1 = value1, @Param2 = value2 , ...{USING transaction_object} ;例
如对于图7-16中创建的存储过程可以声明如下:DECLARE ins_chapter PROCEDURE FOR sp_inser
tchapter cid = :cid, name = :name ;7.6.3 存储过程调用过程执行存储过程:使用EXE
CUTE子句执行存储过程。例如,要执行步骤⑴中声明的存储过程,编写如下:EXECUTE ins_chapter; 提取存储过程返回
参数:使用Fetch子句提取返回值(如果存储过程返回值的话)。 关闭存储过程:使用CLOSE子句关闭存储过程。 7.6.3 存储过
程调用过程例7.11 试用存储过程调用的方式重新设计例7.2,实现把输入的章节编号和章节名称保存到章节表chapter中,程序运行
界面如图7-2所示。 7.7 触发器触发器是一种特殊类型的存储过程,它总是与数据库中的某个表相关联。触发器的主要作用就是能够实现由
主键和外键所不能保证的、复杂的参照完整性和数据一致性。触发器可以被以下的一个或者多个事件触发,如表7-9所示。 7.7.1 触发器
的创建语法Watcom-SQL格式 CREATE?TRIGGER?trigger-name?trigger-time?trigge
r-event?[,?trigger-event,...] [?ORDER?integer?]?ON?table-name [?R
EFERENCING?[?OLD?AS?old-name?] ?????????????????????????????[?NEW
?AS?new-name?]?] ?????????????????????????????[?REMOTE?AS?remote-
name?]?] [?FOR?EACH?{?ROW?|?STATEMENT?}?] [?WHEN?(?search-conditi
on?)?] ??compound-statementCREATE TRIGGER tr_managerBEFORE UPDATE
OF dept_head_idON departmentREFERENCING OLD AS old_dept NEW AS n
ew_deptFOR EACH ROWBEGIN UPDATE employee SET employee.manager
_id=new_dept.dept_head_id WHERE employee.dept_id=old_dept.dept_
idEND 7.7.1 触发器的创建语法Transaction-SQL格式 第一种语法:CREATE?TRIGGER?[owner
.]trigger_name ON?[owner.]table_name FOR?{?INSERT,?UPDATE,?DELETE
?} AS?statement-list第二种语法:CREATE?TRIGGER?[owner.]trigger_name ON?
[owner.]table_name FOR?{INSERT,?UPDATE} AS [?IF?UPDATE?(?column_n
ame?) [?{?AND?|?OR?}?UPDATE?(?column_name?)?]?...?] ??statement-l
ist [?IF?UPDATE?(?column_name?) [?{?AND?|?OR}?UPDATE?(?column_nam
e?)?]?...?] ??statement-list CREATE TRIGGER tr_managerON departme
ntFOR UPDATEAS IF UPDATE(dept_head_id) UPDATE employee
SET employee.manager_id=inserted.dept_head_id WHERE employee.
dept_id=deleted.dept_id 7.7.2 触发器的创建方法Sybase Central中创建触发器PowerBu
ilder中创建触发器: 7.8 本章小结本章主要介绍了PowerBuilder中使用嵌入式SQL语句的语法格式、基本SQL语句
、游标、存储过程、触发器等的创建和应用作了详细的介绍,并且通过具体的示例加以说明。通过本章的学习,应该对嵌入式SQL语句在Powe
rBuilder中的应用有一个深入的理解,同时对于存储过程、触发器等的应用也有所了解。 7.9 本章习题一、填空题1、SQL亦称_
____________,已经被正式作为关系型数据库管理系统的标准语句。2、PowerBuilder中嵌入式SQL语句必须以_______结束,语句中的变量名前必须加_____。3、事务对象SQLCA的属性______的返回值可以指定最近一条SQL语句执行是否成功。4、事务处理SQL语句中,___________用于提交事务,___________用于会滚事务。5、基本SQL语句中,检索和更新数据库中大二进制对象数据分别使用_______和________。6、动态SQL语句使用时需要涉及到_____________对象和______________对象。7、PowerBuilder所提供的动态策略区变量为__________,动态描述区变量为____________。8、Adaptive Server anywhere支持两种语法格式,即__________和___________来创建存储过程和触发器。 7.9 本章习题二、简答题1、在PowerBuilder中,应该如何建立和断开同数据库的连接?2、在PowerBuilder中,应该如何检查嵌入式SQL语句的执行情况?3、在PowerBuilder中,使用游标需要经过那几个步骤?4、在PowerBuilder中,应该如何调用创建的存储过程?7.9 本章习题三、编程题1、 针对第5章所创建的表格chapter和experiment,试分别使用SELECT、INSERT、DELETE、UPDATE、SELECTBLOB、UPDATEBLOB语句对其中的数据进行操作。2、针对第5章所创建的表格chapter,要求使用游标读出表中所有的数据,并且将表中的数据添加到列表框中。
献花(0)
+1
(本文系籽油荃面原创)