db2编程基础要点.docx
《db2编程基础要点.docx》由会员分享,可在线阅读,更多相关《db2编程基础要点.docx(9页珍藏版)》请在冰点文库上搜索。
db2编程基础要点
db2编程基础要点
2008-09-1918:
00
1DB2编程
1.1建存储过程时Create后一定不要用TAB键
createprocedure
的create后只能用空格,而不可用tab健,否则编译会通不过。
切记,切记。
1.2使用临时表
要注意,临时表只能建在usertemporytablesspace上,如果database只有systemtemporytablespace是不能建临时表的。
另外,DB2的临时表和sybase及oracle的临时表不太一样,DB2的临时表是在一个session内有效的。
所以,如果程序有多线程,最好不要用临时表,很难控制。
建临时表时最好加上 with replace选项,这样就可以不显示的drop临时表,建临时表时如果不加该选项而该临时表在该session内已创建且没有drop,这时会发生错误。
1.3从数据表中取指定前几条记录
select * fromtb_market_codefetchfirst1rowsonly
但下面这种方式不允许:
selectmarket_codeintov_market_code
fromtb_market_codefetchfirst1rowsonly;
选第一条记录的字段到一个变量以以下方式代替:
declarev_market_codechar
(1);
declarecursor1cursorforselectmarket_codefromtb_market_code
fetchfirst1rowsonlyforupdate;
opencursor1;
fetchcursor1intov_market_code;
closecursor1;
1.4游标的使用
注意commit和rollback
使用游标时要特别注意如果没有加withhold选项,在Commit和Rollback时,该游标将被关闭。
Commit和Rollback有很多东西要注意。
特别小心。
游标的两种定义方式:
一种为:
declarecontinuehandlerfornotfound
begin
setv_notfound=1;
end;
declarecursor1cursorwithholdfor
selectmarket_codefromtb_market_codeforupdate;
opencursor1;
setv_notfound=0;
fetchcursor1intov_market_code;
whilev_notfound=0Do
--work
setv_notfound=0;
fetchcursor1intov_market_code;
endwhile;
closecursor1;
这种方式使用起来比较复杂,但也比较灵活。
特别是可以使用withhold选项。
如果循环内有commit或rollback而要保持该cursor不被关闭,只能使用这种方式。
另一种为:
pcursor1:
forloopcs1as cousor1 cursor as
select market_code asmarket_code
fromtb_market_code
forupdate
do
endfor;
这种方式的优点是比较简单,不用(也不允许)使用open,fetch,close。
但不能使用with hold选项。
如果在游标循环内要使用commit,rollback则不能使用这种方式。
如果没有commit或rollback的要求,推荐使用这种方式(看来For这种方式有问题)。
修改游标的当前记录的方法
updatetb_market_codesetmarket_code='0'wherecurrentofcursor1;
不过要注意将cursor1定义为可修改的游标
declarecursor1cursorforselectmarket_codefromtb_market_code
forupdate;
forupdate不能和GROUPBY、DISTINCT、ORDERBY、FORREADONLY及UNION,EXCEPT,orINTERSECT但UNIONALL除外)一起使用。
1.5类似decode的转码操作
oracle中有一个函数
selectdecode(a1,'1','n1','2','n2','n3')aa1from
db2没有该函数,但可以用变通的方法。
selectcasea1
when'1'then'n1'
when'2'then'n2'
else'n3'
endasaa1from
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写见sqllibsamplescliudfsrv.c
1.9创建含identity值(即自动生成的ID)的表
建这样的表的写法:
CREATETABLEtest
(t1SMALLINTNOTNULL
GENERATEDALWAYSASIDENTITY
(STARTWITH500,INCREMENTBY1),
t2CHAR
(1));
在一个表中只允许有一个identity的column。
1.10预防字段空值的处理
SELECTDEPTNO,DEPTNAME,COALESCE(MGRNO,'ABSENT'),ADMRDEPT
FROMDEPARTMENT
COALESCE函数返回()中表达式列表中第一个不为空的表达式,可以带多个表达式。
和oracle的isnull类似,但isnull好象只能两个表达式。
1.11取得处理的记录数
declarev_countint;
updatetb_testsett1=’0’
wheret2=’2’;
--检查修改的行数,判断指定的记录是否存在
getdiagnosticsv_count=ROW_COUNT;
只对update,insert,delete起作用.
不对selectinto有效
#p#
1.12从存储过程返回结果集(游标)的用法
1、建一sp返回结果集
CREATEPROCEDUREDB2INST1.Proc1( )
LANGUAGESQL
resultsets2(返回两个结果集)
------------------------------------------------------------------------
--SQL存储过程
------------------------------------------------------------------------
P1:
BEGIN
declarec1cursor withreturntocallerfor
select market_code
from tb_market_code;
--指定该结果集用于返回给调用者
declarec2cursor withreturntocallerfor
select market_code
from tb_market_code;
openc1;
openc2;
ENDP1
2、建一SP调该sp且使用它的结果集
CREATEPROCEDUREDB2INST1.Proc2(
outout_market_codechar
(1))
LANGUAGESQL
------------------------------------------------------------------------
--SQL存储过程
------------------------------------------------------------------------
P1:
BEGIN
declareloc1,loc2result_set_locatorvarying;
--建立一个结果集数组
callproc1;
--调用该SP返回结果集。
associateresultsetlocator(loc1,loc2)withprocedureproc1;
--将返回结果集和结果集数组关联
allocatecursor1cursorforresultsetloc1;
allocatecursor2cursorforresultsetloc2;
--将结果集数组分配给cursor
fetch cursor1intoout_market_code;
--直接从结果集中赋值
closecursor1;
ENDP1
3、动态SQL写法
DECLARECURSORC1FORSTMT1;
PREPARESTMT1FROM
'ALLOCATEC2CURSORFORRESULTSET?
';
4、注意:
一、如果一个sp调用好几次,只能取到最近一次调用的结果集。
二、allocate的cursor不能再次open,但可以close,是closesp中的对应cursor。
1.13类型转换函数
selectcast(currenttimeaschar(8))fromtb_market_code
1.14存储过程的互相调用
目前,csp可以互相调用。
Sqlsp可以互相调用,
Sqlsp可以调用Csp,
但Csp不可以调用Sqlsp(最新的说法是可以)。
1.15C存储过程参数注意
createprocedurepr_clear_task_ctrl(
ININ_BRANCH_CODEchar(4),
ININ_TRADEDATE char(8),
ININ_TASK_ID char
(2),
ININ_SUB_TASK_IDchar(4),
OUTOUT_SUCCESS_FLAGINTEGER)
DYNAMICRESULTSETS0
LANGUAGEC
PARAMETERSTYLEGENERALWITHNULLS(如果不是这样,
sql的sp将不能调用该用c写的存储过程,产生保护性错误)
NODBINFO
FENCED
MODIFIESSQLDATA
EXTERNALNAME'pr_clear_task_ctrl!
pr_clear_task_ctrl'@
1.16存储过程fence及unfence
fence的存储过程单独启用一个新的地址空间,而unfence的存储过程和调用它的进程使用同一个地址空间。
一般而言,fence的存储过程比较安全。
有时一些特殊的要求,如要取调用者的pid,则fence的存储过程会取不到,而只有unfence的能取到。
1.17SP错误处理用法
如果在SP中调用其它的有返回值的,包括结果集、临时表和输出参数类型的SP,DB2会自动发出一个SQLWarning。
而在我们原来的处理中对于SQLWarning都会插入到日志,这样子最后会出现多条SQLCODE=0的警告信息。
处理办法:
定义一个标志变量,比如DECLAREV_STATUSINTEGERDEFAULT0,
在CALLSPNAME之后,SETV_STATUS=1,
DECLARECONTINUEHANDLERFORSQLWARNING
BEGIN
IFV_STATUS<>1THEN
--警告处理,插入日志
SETV_STATUS=0;
ENDIF;
END;
1.18import用法
db2import from gh1.out of DELmessageserr.txtinsertinto db2inst1.tb_dbf_match_ha
注意要加schma。
1.19values的使用
如果有多个set 语句给变量付值,最好使用values语句,改写为一句。
这样可以提高效率。
但要注意,values不能将null值付给一个变量。
values(null)intoout_return_code;
这个语句会报错的。
1.20给select语句指定隔离级别
select*fromtb_head_stock_balancewithur
1.21atomic及notatomic区别
atomic是将该部分程序块指定为一个整体,其中任何一个语句失败,则整个程序块都相当于没做,包括包含在atomic块内的已经执行成功的语句也相当于没做,有点类似于transaction。
原文网址:
由弘一网童保存,尚未注册。
注册