讲解DB2数据库编程所应掌握的基本知识

  • 来源: 赛迪网 作者: 若水   2008-04-26/15:46
  • . DB2数据库编程

     

    ◆1.1 建存储过程时Create 后一定不要用TAB键

     

    create procedure

    的create后只能用空格,而不可用tab健,否则编译会通不过。

    切记,切记。

     

    ◆1.2 使用临时表

     

    要注意,临时表只能建在user tempory tables space 上,如果database只有system tempory table space是不能建临时表的。

     

    另外,DB2的临时表和sybase及oracle的临时表不太一样,DB2的临时表是在一个session内有效的。所以,如果程序有多线程,最好不要用临时表,很难控制。

     

    建临时表时最好加上 with replace选项,这样就可以不显示的drop 临时表,建临时表时如果不加该选项而该临时表在该session内已创建且没有drop,这时会发生错误。

     

    ◆1.3 从数据表中取指定前几条记录

     

    select * from tb_market_code fetch first 1 rows only

     

     

    但下面这种方式不允许:

     

    select market_code into v_market_code from tb_market_code fetch first 1 rows only;

     

     

    选第一条记录的字段到一个变量以以下方式代替:

     

    declare v_market_code char(1); declare cursor1 cursor for select market_code from tb_market_code fetch first 1 rows only for update; open cursor1; fetch cursor1 into v_market_code; close cursor1;

     

     

    ◆1.4 游标的使用

     

    注意commit和rollback

    使用游标时要特别注意如果没有加with hold 选项,在Commit和Rollback时,该游标将被关闭。Commit 和Rollback有很多东西要注意。特别小心。

     

    游标的两种定义方式:

     

    一种为:

     

    declare continue handler for not found begin set v_notfound = 1; end; declare cursor1 cursor with hold for select market_code from tb_market_code for update; open cursor1; set v_notfound=0; fetch cursor1 into v_market_code; while v_notfound=0 Do --work set v_notfound=0; fetch cursor1 into v_market_code; end while; close cursor1;

     

     

    这种方式使用起来比较复杂,但也比较灵活。特别是可以使用with hold 选项。如果循环内有commit或rollback 而要保持该cursor不被关闭,只能使用这种方式。

     

    另一种为:

     

    pcursor1: for loopcs1 as cousor1 cursor as select market_code as market_code from tb_market_code for update do end for;

     

     

    这种方式的优点是比较简单,不用(也不允许)使用open,fetch,close。

    但不能使用with hold 选项。如果在游标循环内要使用commit,rollback则不能使用这种方式。如果没有commit或rollback的要求,推荐使用这种方式(看来For这种方式有问题)。

    修改游标的当前记录的方法

     

    update tb_market_code set market_code='0' where current of cursor1;

     

     

    不过要注意将cursor1定义为可修改的游标

     

    declare cursor1 cursor for select market_code from tb_market_code for update;

     

     

    for update 不能和GROUP BY、 DISTINCT、 ORDER BY、 FOR READ ONLY及UNION, EXCEPT, or INTERSECT但 UNION ALL除外)一起使用。

     

    ◆1.5 类似decode的转码操作

    oracle中有一个函数

     

    select decode(a1,'1','n1','2','n2','n3') aa1 from

     

     

    db2没有该函数,但可以用变通的方法。 #p#分页标题#e#

     

    select case a1 when '1' then 'n1' when '2' then 'n2' else 'n3' end as aa1 from

     

     

    ◆1.6 类似charindex查找字符在字串中的位置

     

    Locate(‘y’,’dfdasfay’)

    查找’y’ 在’dfdasfay’中的位置。

     

    ◆1.7 类似datedif计算两个日期的相差天数

     

    days(date(‘2001-06-05’)) – days(date(‘2001-04-01’))

    days 返回的是从 0001-01-01 开始计算的天数

     

    ◆1.8 写UDF的例子

     

    C写见sqllib\samples\cli\udfsrv.c

     

    ◆1.9 创建含identity值(即自动生成的ID)的表

     

    建这样的表的写法:

     

    CREATE TABLE test (t1 SMALLINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 500, INCREMENT BY 1), t2 CHAR(1));

     

     

    在一个表中只允许有一个identity的column。

     

    ◆1.10 预防字段空值的处理

     

    SELECT DEPTNO ,DEPTNAME ,COALESCE(MGRNO ,'ABSENT'),ADMRDEPT FROM DEPARTMENT

     

     

    COALESCE函数返回()中表达式列表中第一个不为空的表达式,可以带多个表达式。

    和oracle的isnull类似,但isnull好象只能两个表达式。

     

    ◆1.11 取得处理的记录数

     

    declare v_count int; update tb_test set t1=’0’ where t2=’2’; --检查修改的行数,判断指定的记录是否存在 get diagnostics v_ count=ROW_COUNT;

     

     

    只对update,insert,delete起作用.

    不对select into 有效

     

    ◆1.12 从存储过程返回结果集(游标)的用法

     

    (1)建一sp返回结果集

     

    CREATE PROCEDURE DB2INST1.Proc1 ( ) LANGUAGE SQL result sets 2(返回两个结果集) ------------------------------------------------------------------------ -- SQL 存储过程 ------------------------------------------------------------------------ P1: BEGIN declare c1 cursor with return to caller for select market_code from tb_market_code; --指定该结果集用于返回给调用者 declare c2 cursor with return to caller for select market_code from tb_market_code; open c1; open c2; END P1

     

     

    (2)建一SP调该sp且使用它的结果集

     

    CREATE PROCEDURE DB2INST1.Proc2 ( out out_market_code char(1)) LANGUAGE SQL ------------------------------------------------------------------------ -- SQL 存储过程 ------------------------------------------------------------------------ P1: BEGIN declare loc1,loc2 result_set_locator varying; --建立一个结果集数组 call proc1; --调用该SP返回结果集。 associate result set locator(loc1,loc2) with procedure proc1; --将返回结果集和结果集数组关联 allocate cursor1 cursor for result set loc1; allocate cursor2 cursor for result set loc2; --将结果集数组分配给cursor fetch cursor1 into out_market_code; --直接从结果集中赋值 close cursor1; END P1

     

     

    (3)动态SQL写法

     

    DECLARE CURSOR C1 FOR STMT1; PREPARE STMT1 FROM 'ALLOCATE C2 CURSOR FOR RESULT SET ?';

     

     

    (4)注意:

    一、 如果一个sp调用好几次,只能取到最近一次调用的结果集。

    二、 allocate的cursor不能再次open,但可以close,是close sp中的对应cursor。

     

    ◆1.13 类型转换函数

     

    select cast ( current time as char(8)) from tb_market_code #p#分页标题#e#

     

     

    ◆1.14 存储过程的互相调用

     

    目前,c sp可以互相调用。

    Sql sp 可以互相调用,

    Sql sp 可以调用C sp,

    但C sp 不可以调用Sql sp(最新的说法是可以)。

     

    ◆1.15 C存储过程参数注意

     

    create procedure pr_clear_task_ctrl( IN IN_BRANCH_CODE char(4), IN IN_TRADEDATE char(8), IN IN_TASK_ID char(2), IN IN_SUB_TASK_ID char(4), OUT OUT_SUCCESS_FLAG INTEGER ) DYNAMIC RESULT SETS 0 LANGUAGE C PARAMETER STYLE GENERAL WITH NULLS(如果不是这样,sql 的sp将不能调用该用c写的存储过程,产生保护性错误) NO DBINFO FENCED MODIFIES SQL DATA EXTERNAL NAME 'pr_clear_task_ctrl!pr_clear_task_ctrl'@

     

     

    ◆1.16 存储过程fence及unfence

     

    fence的存储过程单独启用一个新的地址空间,而unfence的存储过程和调用它的进程使用同一个地址空间。一般而言,fence的存储过程比较安全。有时一些特殊的要求,如要取调用者的pid,则fence的存储过程会取不到,而只有unfence的能取到。


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多