---------------------------游标---------------------------------
--游标(cursor) -- 游标就是一个指针,有点像Java中的list类,用来定义一个集合,并允许遍历这个集合。从而使我们处理集合中的单个记录 -- 语法:declare <cursor-name> cursor [without hold | with hold ] -- [without return | with return to caller | with return to client ] -- for <select-statement> -- 例子:declare mycr cursor for with return to caller select * from table; --说明: -- without return / with return 选项指定游标的结果集是否要返回 -- with return to caller 将游标的结果集返回给调用者 -- with return client 将游标的结果集返回给客户机应用程序 -- with hold/without hold 选项定义commit操作之后的游标状态(open/close) -- --打开游标:open <cursor-name> -- 从游标中获取数据: -- 语法:fetch <field> from <cursor-name> into <variables> -- 翻译:从游标名中提取数据(字段)到变量当中 -- 例子:fetch mycr into :myvar(宿主变量) --关闭游标close<cursor-name> -- --SQL PL支持两种注释。 -- 单行注释:使用-- -- 多行注释:/**/ /* 复合语句(compound statement) 大多数程序设计语言使用大括号来定义复合语句,将大括号中的语句看做一个整体,SQL PL也可以定义复合语句, 语法: label:begin[atomic | not atomic] 变量声明,过程逻辑等 end label 例子: p1:begin declare var1 int; declare var2 int; end p1 例子2: begin atomic declare var1 int; declare var2 int; end 当begin后紧跟atomic关键字时,其封装的复合语句就被当做一个处理的单元,也就是说,复合语句中的所有程序指令和语句都必须成功运行 如果其中一个语句发生错误,那么整个存储过程所执行的结果都将回滚。 */ /* if语句 学过任何一种程序语言的人对if语句应该都非常熟悉,SQL PL语句的if格式: if <condition> then <SQL procedure statement> elseif <condition> then <SQL procedure statement> end if; 连接数据库 connect to sample 创建存储过程 create procedure testif (in friend varchar(10),out msg varchar(30)) language SQL begin if friend='张三' then set msg='你好,张三'; elseif friend='李四' then set msg='你好,李四'; else set msg='对不起,我不认识你'; end if; end! --调用存储过程 call testif('张三',?)! call testif('王五',?)! --删除存储过程 drop procedure testif! --关闭连接 connect reset! 运行示例: 将上面的代码保存为c:\test_if.sql,然后在DB2命令窗口中执行如下命令 db2 -td! -vf c:\test_if.sql 除了if语句外,case语句也可以实现分支判断的功能。 */ --异常处理(sqlcode) /* 1.sqlcode=0 该sql执行成功 2.sqlcode>0 该sql执行成功,但是返回一个警告 3.sqlcode<0 该sql执行失败,并且返回了一个错误 4.sqlcode=100 未找到指定值 */ --sqlstate是一个遵守ISO/ANSI SQL92标准的长为5个字符的字符串,这些值得意义如下: /* 1.sqlstate='00000' 成功 2.sqlstate='01xxx' 警告 3.sqlstate='02000' 未找到 4.其他值为错误 我们也可以自己定义sqlstate,它必须是5个字符串且必须要以数字7.8或9或者字母I到Z开始。 注:sqlstate是标准,它在各RDBMS间是相同的,一般定义的比较笼统 sqlcode在各个RDBMS是不同的,它比sqlstate更具体,通常,几个sqlcode可能对应一个sqlstate 值得注意的是,要在SQL PL中使用sqlcode和sqlstate,我们必须要声明他们,如下: declare sqlcode int default 0; declare sqlstate char(5) default '00000' */ --比较Java的异常处理机制和SQL PL的异常处理机制 /* 在Java中,我们可以通过继承Exception类来定义自己的异常类,在SQL PL中,我们可以给特定的sqlstate声明一个自定义的名称, 可以在后面的sql中使用它。 例如: sqlstate='01004'表示字符串数据被截断,在下的语句可以将该sqlstate命名为trunc: 语法: declare <condition-name> condition for sqlstate <sting-constant>; 例: declare truc condition for sqlstate '01004' 以下是预定义的sqlstate名称,无需定义就可以在SQL PL中使用: sqlstate='01xxx' sqlwarning sqlstate='02000' not found 其他 sqlstate sqlexception 在Java中,我们可以通过throw语句显示抛出异常,在SQL PL中signal语句可实现同样的功能。 语法: signal sqlstate <string-constant> set message_text=<variable-name or string-constant>; Java中,当程序出现运行时错误时,程序将跳转到异常处理模块。在SQL PL中也可以定义异常模块。 通常,当SQL在运行中出现错误时,SQL就会终止并返回客户端一个错误消息。我们也可以给一个特定类型的错误定义一个处理程序,这样,当SQL在 运行中出现这类错误时,程序就是跳转到该异常处理模块。 语法: declare [continue | exit | undo] handler for <condition> <sql-procedure-statement> 说明: continue表示,当异常抛出后,由对应的异常处理器解决异常,工作流会继续执行抛出异常语句的下一条语句。 exit表示,当抛出异常后,对应的异常处理器结局此异常情况,工作流直接到程序的末尾 undo表示,当抛出异常后,对应的异常处理器解决此异常情况,工作流直接到达程序的末尾并且撤销所有专辑实现的操作,或者回滚所有已执行的语句 */ --动态SQL(dynamic sql) /* 动态SQL是程序运行时构造的,要执行单条SQL,使用EXECUTE IMMEDATE语句,当批量执行SQL时,先使用prepare语句构造SQL,然后使用execute 语句执行。 prepare语句:用来构造批量SQL 语法: prepare <sql-statemanet> [output] into <result> [input into] <input> from <variable> describe语句:获取表,SQL等数据库对象的描述信息 execute语句:用来执行批量SQL,不能执行select语句 语法:EXECUTE <statement-name> [into <result-variable>] [using <input-variable> { <input-variable>] ] execute immediate语句:用来执行单条SQL语句,不能执行select语句 execute immediate <sql-statement> 内联SQL PL(inline SQL PL) 通常SQL PL只能使用在存储过程、触发器。用户自定义函数中,但是有一部分SQL PL 也可以直接在命令行编辑器或脚本中使用,它们是: declare <variable> set case for get diagnostics goto if return signal while iterate leave */