---------------------------游标---------------------------------

--游标(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
*/

 

posted @ 2017-01-10 15:31  feng_kui  阅读(237)  评论(0编辑  收藏  举报