db2 调用存储过程
DB2 存储过程开发最佳实践
DB2 存储过程开发最佳实践COALESCE函数会依次检查输入的参数,返回第一个不是NULL的参数,只有当传入COALESCE函数的所有的参数都是NULL的时候,函数才会返回NULL。
例如, COALESCE(piName,''),如果变量piName为NULL,那么函数会返回'',否则就会返回piName本身的值。
下面的例子展示了如何对参数进行检查何初始化。
Person表用来存储个人的基本信息,其定义如下:表1: Person下面是用于向表Person插入数据的存储过程的参数预处理部分代码:表Person中num、name和age都是非空字段。
对于name字段,多个空格我们也认为是空值,所以在进行判断前我们调用RTRIM和COALESCE对其进行处理,然后使用 piName = '',对其进行非空判断;对于Rank 字段,我们希望如果用户输入的NULL,我们把它设置成"0",对其我们也使用COALESCE进行初始化;对于"Age"和"Num" 我们直接使用 IS NULL进行非空判断就可以了。
如果输入参数没有通过非空判断,我们就对输出参数poGenStatus设置一个确定的值(例子中为 34100)告知调用者:输入参数错误。
下面是对参数初始化规则的一个总结,供大家参考:1. 输入参数为字符类型,且允许为空的,可以使用COALESCE(inputParameter,'')把NULL转换成'';2. 输入类型为整型,且允许为空的,可以使用COALESCE(inputParameter,0),把空转换成0;3. 输入参数为字符类型,且是非空非空格的,可以使用COALESCE(inputParameter,'')把NULL转换成'',然后判断函数返回值是否为'';4. 输入类型为整型,且是非空的,不需要使用COALESCE函数,直接使用IS NULL进行非空判断。
DB2_存储过程执行计划的查看及监控方法
一,编写存储过程。
[db2inst1@db2lab ~]$ cat test.sqlcreate procedure sales_status(in quota integer)dynamic result sets 2language sqlbegindeclare SQLSTATE char(5);declare rs cursor with return forselect * from t1;open rs;end@二,建立存储过程[db2inst1@db2lab~]$**************DB20000I The SQL command completed successfully.三,执行存储过程[db2inst1@db2lab ~]$ db2 "call sales_status(1)"Result set 1--------------ID-------1.1 record(s) selected.Return Status = 0四,利用表函数MON_GET_PKG_CACHE_STMT抓取static的信息,获取PACKAGE_NAME及SQL语句[db2inst1@db2lab ~]$ db2 "selectPACKAGE_NAME,SECTION_NUMBER,EXECUTABLE_IDfrom TABLE(MON_GET_PKG_CACHE_STMT ( 'S', NULL, NULL, -1)) as T" PACKAGE_NAMESECTION_NUMBER EXECUTABLE_ID -------------------------------------------------------------------------------------------------------------------------------- -------------------- -------------------------------------------------------------------P04624831x'0100000000000000BE0100000000000001000000010020140415004624839232' 1 record(s) selected.五,利用EXECUTABLE_ID,获取SQL语句[db2inst1@db2lab ~]$ db2 "SELECT STMT_TEXT FROMTABLE(MON_GET_PKG_CACHE_STMT> (null,x'0100000000000000BE0100000000000001000000010020140415004624839232', null, -2))"STMT_TEXT-------------------------------------------------------DECLARE RS cursor with return forselect * from T1 where ID = :HV00008 :HI000081 record(s) selected.六,查看package_name信息,valid列信息需要重点关注,信息中心解释如下:•N = Needs rebinding•V = Validate at run time•X = Package is inoperative because some function instance on which it depends has been dropped; explicit rebind is needed•Y = Valid[db2inst1@db2lab ~]$ db2 list packages for all |grep -i P0462483Bound Total Isolation Package Schema Version by sections Valid Format level Blocking----------- --------- ----------- --------- ------------- ------- -------- --------- --------P0462483 DB2INST1 DB2INST1 1Y 0 CS U七,获取该package_name的执行计划信息[db2inst1@db2lab ~]$ db2expln -d pos -g -c db2inst1 -p P0462483 -s 0 -tDB2 Universal Database Version 9.7, 5622-044 (c) Copyright IBM Corp. 1991, 2008 Licensed Material - Program Property of IBMIBM DB2 Universal Database SQL and XQUERY Explain Tool******************** PACKAGE ***************************************Package Name = "DB2INST1"."P0462483" Version =Prep Date = 2014/04/15Prep Time = 00:46:24Bind Timestamp = 2014-04-15-00.46.24.839232Isolation Level = Cursor StabilityBlocking = Block Unambiguous CursorsQuery Optimization Class = 5Partition Parallel = NoIntra-Partition Parallel = NoSQL Path = "SYSIBM", "SYSFUN", "SYSPROC", "SYSIBMADM","DB2INST1"-------------------- SECTION ---------------------------------------Section = 1Statement:DECLARE RS cursorwith returnforselect *from T1where ID =:HV00008 :HI00008Section Code Page = 1208Estimated Cost = 7.569436Estimated Cardinality = 1.000000Access Table Name = DB2INST1.T1 ID = 2,4| #Columns = 1| Skip Inserted Rows| Evaluate Block/Data Predicates Before Locking Committed Row| May participate in Scan Sharing structures| Scan may start anywhere and wrap, for completion| Fast scan, for purposes of scan sharing management| Scan can be throttled in scan sharing management| Relation Scan| | Prefetch: Eligible| Lock Intents| | Table: Intent Share| | Row : Next Key Share| Sargable Predicate(s)| | #Predicates = 1| | Return Data to Application| | | #Columns = 1Return Data CompletionEnd of sectionOptimizer Plan:RowsOperator(ID)Cost1RETURN( 1)7.56944|1TBSCAN( 2)7.56944|1Table:DB2INST1T1总结:DB2的执行计划变化较多,不经常runstats和rebind的时候,有可能本地执行计划很好,但在实际生产环境上执行计划较差,这需要DBA能抓取实时SQL执行计划,静态sql通过上述方式抓取,动态sql需要借助db2expln的cache选项抓取,来分析sql的消耗情况Dynamic Statement Options:-cache <anchID>,<stmtUID>,<envID>,<varID>= Retrieve the statement identified by the given IDsfrom the dynamic SQL cache. (The IDs can beobtained by running db2pd with the -dynamicoption.。
DB2存储过程(Merge关键字的使用)
DB2存储过程(Merge关键字的使用)CREATE PROCEDURE COPY_OCJ_LIST_TO_SHIPMENT(IN P_SESSION_ID VARCHAR(40), --当前用户的session ID IN P_IS_REPEAT VARCHAR(20), --如果导入新数据传入值:YES,如果导入全部数据传入值:ALLIN P_IS_SAME VARCHAR(20), --是否保存IN P_ORDER_TYPE VARCHAR(20), --客户发货入库IN P_ORDER_ID VARCHAR(20), --入库编号IN P_ORDER_TIME VARCHAR(30), --入库时间IN P_VENDOR_ID VARCHAR(20), --发货客户IN P_WAREHOUSE_ID VARCHAR(20),--分拨中心IN P_CREATE_BY VARCHAR(20) --创建者)MODIFIES SQL DATA --表示存储过程可以执行任何 SQL 语句LANGUAGE SQL-------------------------------------------------------------------------- SQL 存储过程------------------------------------------------------------------------P1: BEGIN ATOMIC--声明一个变量,用来保存入库计划明细中未失效运单的数量DECLARE D_ODRER_COUNT INTEGER;DECLARE D_ORDER_ID VARCHAR(20);--------------------------- 保存OCJ正式表数据 ---------------------------MERGE INTO OCJ_SHIPMENT OSUSING(--查询OCJ导入的临时表数据SELECTSHIPMENT_ID, --IDSHIPMENT_PLAN_NO, --运单号RECEIVE_DATE, --提货日期VENDOR_ID, --发货客户WAREHOUSE_ID, --原分拨中心IS_CHECK, --是否审核CAR_LICENSE_NO, --车辆牌号DRIVER_NAME, --司机名称STATE, --状态CREATE_BY, --创建者CREATE_DATE, --创建日期LAST_UPDATE_BY, --修改者LAST_UPDATE_DATE, --修改日期SESSION_ID, --用户IDSERIAL_ID, --序列号IS_REPEAT, --是否重复FROM_WAREHOUSE_ID, --来源分拨中心IS_SAME_WAREHOUSE --是否同一分拨中心FROM OCJ_SHIPMENT_TEMPWHERE SESSION_ID = P_SESSION_ID AND IS_REPEAT != P_IS_REPEAT)OSTON(OST.IS_REPEAT != P_IS_REPEAT ANDOS.SHIPMENT_PLAN_NO=OST.SHIPMENT_PLAN_NO ANDOS.VENDOR_ID=OST.VENDOR_ID) --如果临时表中标记为YS_Yes的,则修改WHEN MATCHED THEN--如果指定的条件匹配,则执行修改动作UPDATE SETOS.SHIPMENT_PLAN_NO=OST.SHIPMENT_PLAN_NO, --运单号OS.RECEIVE_DATE=OST.RECEIVE_DATE, --提货日期OS.VENDOR_ID=OST.VENDOR_ID, --发货客户OS.WAREHOUSE_ID =OST.WAREHOUSE_ID, --原分拨中心OS.FROM_WAREHOUSE_ID=OST.FROM_WAREHOUSE_ID, --来源分拨中心OS.IS_CHECK=OST.IS_CHECK, --是否审核OS.CAR_LICENSE_NO=OST.CAR_LICENSE_NO, --车辆编号OS.DRIVER_NAME=OST.DRIVER_NAME, --司机名称OS.STATE=OST.STATE, --状态ST_UPDATE_BY=ST_UPDATE_BY, --修改者ST_UPDATE_DATE=ST_UPDATE_DATE --修改日期WHEN NOT MATCHED THEN--如果指定的条件不匹配,则执行添加动作INSERT(SHIPMENT_ID, --IDSHIPMENT_PLAN_NO, --运单号RECEIVE_DATE, --提货日期VENDOR_ID, --发货客户WAREHOUSE_ID, --原分拨中心 IS_CHECK, --是否审核CAR_LICENSE_NO, --车辆牌号DRIVER_NAME, --司机名称STATE, --状态CREATE_BY, --创建者CREATE_DATE, --创建日期LAST_UPDATE_BY, --修改者LAST_UPDATE_DATE, --修改日期FROM_WAREHOUSE_ID --来源分拨中心 )VALUES(OST.SHIPMENT_ID,OST.SHIPMENT_PLAN_NO,OST.RECEIVE_DATE,OST.VENDOR_ID,OST.WAREHOUSE_ID,OST.IS_CHECK,OST.CAR_LICENSE_NO,OST.DRIVER_NAME,OST.STATE,OST.CREATE_BY,OST.CREATE_DATE,ST_UPDATE_BY,ST_UPDATE_DATE,OST.FROM_WAREHOUSE_ID);-------------------------------- 保存导入数据状态表状态 --------------------------------MERGE INTO SHIPMENT_STATE SSUSING(--查询OCJ导入的临时表数据SELECTSHIPMENT_ID, --IDSHIPMENT_PLAN_NO, --运单号RECEIVE_DATE, --提货日期VENDOR_ID, --发货客户WAREHOUSE_ID, --原分拨中心--IS_CHECK, --是否审核--CAR_LICENSE_NO, --车辆牌号--DRIVER_NAME, --司机名称--STATE, --状态--CREATE_BY, --创建者--CREATE_DATE, --创建日期--LAST_UPDATE_BY, --修改者--LAST_UPDATE_DATE, --修改日期--SESSION_ID, --用户ID--SERIAL_ID, --序列号IS_REPEAT --是否重复--FROM_WAREHOUSE_ID, --来源分拨中心--IS_SAME_WAREHOUSE --是否同一分拨中心FROM OCJ_SHIPMENT_TEMPWHERE SESSION_ID = P_SESSION_ID AND IS_REPEAT != P_IS_REPEAT)OSTON(OST.IS_REPEAT != P_IS_REPEAT ANDSS.SHIPMENT_PLAN_NO=OST.SHIPMENT_PLAN_NO ANDSS.VENDOR_ID=OST.VENDOR_ID) --如果临时表中标记为YS_Yes的,则修改WHEN MATCHED THEN--如果指定的条件匹配,则执行修改动作UPDATE SETSS.RECEIVE_DATE=OST.RECEIVE_DATE --提货日期WHEN NOT MATCHED THEN--如果指定的条件不匹配,则执行添加动作INSERT(SHIPMENT_STATE_ID, --状态表ID(唯一的) SHIPMENT_PLAN_NO, --运单号RECEIVE_DATE, --提货日期VENDOR_ID, --发货客户WAREHOUSE_ID --原分拨中心--CREATE_BY, --创建者--CREATE_DATE --创建日期)VALUES('SS' || OST.SHIPMENT_ID,OST.SHIPMENT_PLAN_NO,OST.RECEIVE_DATE,OST.VENDOR_ID,OST.WAREHOUSE_ID--OST.CREATE_BY, --创建者--OST.CREATE_DATE --创建日期);------------------------------------- 保存导入数据Other状态表状态 -------------------------------------MERGE INTO SHIPMENT_OTHER_STATE SOSUSING(--查询OCJ导入的临时表数据SELECTSHIPMENT_ID, --IDSHIPMENT_PLAN_NO, --运单号RECEIVE_DATE, --提货日期VENDOR_ID, --发货客户--WAREHOUSE_ID, --原分拨中心--IS_CHECK, --是否审核--CAR_LICENSE_NO, --车辆牌号--DRIVER_NAME, --司机名称--STATE, --状态--CREATE_BY, --创建者--CREATE_DATE, --创建日期--LAST_UPDATE_BY, --修改者--LAST_UPDATE_DATE, --修改日期IS_REPEAT, --是否重复FROM_WAREHOUSE_ID, --来源分拨中心IS_SAME_WAREHOUSE --是否同一分拨中心FROM OCJ_SHIPMENT_TEMPWHERE SESSION_ID = P_SESSION_ID AND IS_REPEAT !=P_IS_REPEAT)OSTON(OST.IS_REPEAT != P_IS_REPEAT ANDSOS.SHIPMENT_PLAN_NO=OST.SHIPMENT_PLAN_NO ANDSOS.VENDOR_ID=OST.VENDOR_ID) --如果临时表中标记为YS_Yes的,则修改WHEN MATCHED THEN--如果指定的条件匹配,则执行修改动作UPDATE SETSOS.PLAN_WAREHOUSE_ID=OST.FROM_WAREHOUSE_ID, --来源分拨中心SOS.PLAN_IMPORT='YS_Yes', --可导入SOS.OCJ_IMPORT='YS_Yes', --可导入SOS.OCJ_CHECK='YS_Yes', --可审核SOS.INCOME_ORDER='YS_Yes', --可入库SOS.BOOK_LOC='YS_Yes' --可预排库位ST_UPDATE_BY=ST_UPDATE_BY, --修改者ST_UPDATE_DATE=ST_UPDATE_DATE --修改日期WHEN NOT MATCHED THEN--如果指定的条件不匹配,则执行添加动作INSERT(SHIPMENT_STATE_ID, --状态表ID(唯一的) SHIPMENT_PLAN_NO, --运单号VENDOR_ID, --发货客户PLAN_WAREHOUSE_ID, --来源分拨中心PLAN_IMPORT, --可导入OCJ_IMPORT, --可导入OCJ_CHECK, --可审核INCOME_ORDER, --可入库BOOK_LOC --可预排库位--CREATE_BY, --创建者--CREATE_DATE --创建日期)VALUES('SOS' || OST.SHIPMENT_ID,OST.SHIPMENT_PLAN_NO,OST.VENDOR_ID,OST.FROM_WAREHOUSE_ID,'YS_Yes','YS_Yes','YS_Yes','YS_Yes','YS_Yes'--OST.CREATE_BY, --创建者--OST.CREATE_DATE --创建日期);---------------------------- 保存计划入库头信息 ----------------------------INSERT INTO WMS_INCOMING_ORDER_PLAN (ORDER_ID, --入库计划ID ORDER_NO, --入库计划单号ORDER_TIME, --入库时间ORDER_TYPE, --类型ENTER_TYPE, --自动STATE, --状态CREATE_BY, --创建者CREATE_DATE, --创建时间WAREHOUSE_ID, --分拨中心VENDOR_ID --发货客户)VALUES(P_ORDER_ID,'JHRKD' || P_ORDER_ID,P_ORDER_TIME,P_ORDER_TYPE,'AUTO','State_All_Y',P_CREATE_BY,P_ORDER_TIME,P_WAREHOUSE_ID,P_VENDOR_ID);------------------------------ 修改计划入库明细信息 ------------------------------MERGE INTO WMS_INCOMING_ORDER_ITEM_PLAN WIOIUSING(--查询OCJ导入的临时表数据SELECTSHIPMENT_ID, --IDSHIPMENT_PLAN_NO, --运单号RECEIVE_DATE, --提货日期VENDOR_ID, --发货客户WAREHOUSE_ID, --原分拨中心--IS_CHECK, --是否审核--CAR_LICENSE_NO, --车辆牌号--DRIVER_NAME, --司机名称--STATE, --状态--CREATE_BY, --创建者--CREATE_DATE, --创建日期--LAST_UPDATE_BY, --修改者--LAST_UPDATE_DATE, --修改日期IS_REPEAT, --是否重复FROM_WAREHOUSE_ID, --来源分拨中心IS_SAME_WAREHOUSE --是否同一分拨中心FROM OCJ_SHIPMENT_TEMPWHERE SESSION_ID = P_SESSION_ID AND IS_REPEAT !=P_IS_REPEAT AND IS_SAME_WAREHOUSE='YS_No' --查询当前用户下不同分拨中心的运单信息)OSTON(1=1 AND OST.IS_SAME_WAREHOUSE = 'YS_No' AND WIOI.SHIPMENT_PLAN_NO=OST.SHIPMENT_PLAN_NO ANDWIOI.VENDOR_ID=OST.VENDOR_ID --指定条件)WHEN MATCHED THEN--如果指定的条件匹配,则执行修改动作UPDATE SETSTATE = 'State_All_N';------------------------------ 保存计划入库明细信息 ------------------------------MERGE INTO WMS_INCOMING_ORDER_ITEM_PLAN WIOI USING(--查询OCJ导入的临时表数据SELECTSHIPMENT_ID, --IDSHIPMENT_PLAN_NO, --运单号RECEIVE_DATE, --提货日期VENDOR_ID, --发货客户WAREHOUSE_ID, --原分拨中心--IS_CHECK, --是否审核--CAR_LICENSE_NO, --车辆牌号--DRIVER_NAME, --司机名称--STATE, --状态--CREATE_BY, --创建者--CREATE_DATE, --创建日期--LAST_UPDATE_BY, --修改者--LAST_UPDATE_DATE, --修改日期IS_REPEAT, --是否重复FROM_WAREHOUSE_ID, --来源分拨中心IS_SAME_WAREHOUSE --是否同一分拨中心 FROM OCJ_SHIPMENT_TEMPWHERE SESSION_ID = P_SESSION_ID AND IS_REPEAT != P_IS_REPEAT AND IS_SAME_WAREHOUSE IS NOT NULL)OSTON(1 <> 1 --指定条件)WHEN NOT MATCHED THEN--如果指定的条件不匹配,则执行添加动作INSERT(ORDER_ITEM_ID, --明细IDORDER_ID, --头信息IDSHIPMENT_PLAN_ID, --配送计划IDSHIPMENT_PLAN_NO, --运单号CHECK_STATE, --VENDOR_ID, --发货客户WAREHOUSE_ID, --分拨中心LOC_ID, --库位IDQUANTITY, --数量STATE, --状态CREATE_BY, --创建者CREATE_DATE --创建日期)VALUES('WOIO' || SHIPMENT_ID,P_ORDER_ID,'-',OST.SHIPMENT_PLAN_NO,'YS_No',OST.VENDOR_ID,OST.WAREHOUSE_ID,'-',1,'State_All_Y',P_CREATE_BY,P_ORDER_TIME);------------------------- 修改计划入库信息 ---------------------------如果在入库计划明细中当前ORDER_ID下,不存在状态为State_All_Y,则更新头部信息为State_All_N--查询入库计划表表中有效运单的数据,根据ORDER_ID分组,如果该ORDER_ID下没有有效的入库计划明细,则头部信息失效FOR V ASSELECT count(*) AS count,WIOIP.order_id FROMWMS_INCOMING_ORDER_ITEM_PLAN WIOIPWHERE 1 = 1 AND WIOIP.STATE = 'State_All_Y' --状态为有效的GROUP BY WIOIP.order_id --根据ORDER_ID分组FOR READ ONLYDOSET D_ORDER_ID = V.order_id;SET D_ODRER_COUNT = V.COUNT;--如果有效运单为0,更新头部信息为失效IF D_ODRER_COUNT = 0 THENUPDATE WMS_INCOMING_ORDER_PLAN SET STATE ='State_All_N' WHERE ORDER_ID = D_ORDER_ID;END IF;END FOR;---------------------------------- 添加操作历史初始导入记录 ----------------------------------INSERT INTO ACTION_HISTORY (HISTORY_ID --操作历史ID, REFRENCE_ID --引用ID, REFRENCE_TYPE --操作类型, REFRENCE_OPERATOR --, WAREHOUSE_ID --分拨中心, SUB_WAREHOUSE_ID --, LOC_ID --库位, BEGIN_TIME --开始时间, STATE --状态, COMMENTS --备注, CREATE_BY --创建者, CREATE_DATE --创建时间, LAST_UPDATE_BY --最后修改者, LAST_UPDATE_DATE --最后修改时间, DRIVER_NAME --司机名称, CAR_LICENSE_NO --车辆编号, SHIPMENT_PLAN_ID --配送计划ID , VENDOR_ID --发货客户, SHIPMENT_PLAN_NO --运单号)SELECT 'AHO' || SHIPMENT_ID --操作历史ID, SHIPMENT_ID --引用ID, 'OPERATOR_SHIPMENT_OCJ_IMPORT' --操作类型, 'NEW_OCJ_IMPORT' --, FROM_WAREHOUSE_ID --, '-' --库位, CREATE_DATE --开始时间, 'State_All_Y' --状态, '' --备注, CREATE_BY --创建者, CREATE_DATE --创建时间, CREATE_BY --最后修改者, CREATE_DATE --最后修改时间, DRIVER_NAME --司机名称, CAR_LICENSE_NO --车辆编号, '-' --配送计划ID, VENDOR_ID --发货客户, SHIPMENT_PLAN_NO --运单号FROM OCJ_SHIPMENT_TEMPWHERE SESSION_ID = P_SESSION_ID AND IS_REPEAT = 'YS_No';--初始导入---------------------------------- 添加操作历史覆盖导入记录 ----------------------------------INSERT INTO ACTION_HISTORY(HISTORY_ID --操作历史ID, REFRENCE_ID --引用ID , REFRENCE_TYPE --操作类型, REFRENCE_OPERATOR --, WAREHOUSE_ID --分拨中心, LOC_ID --库位 , BEGIN_TIME --开始时间, STATE --状态 , COMMENTS --备注 , CREATE_BY --创建者 , CREATE_DATE --创建时间, LAST_UPDATE_BY --最后修改者, LAST_UPDATE_DATE --最后修改时间, DRIVER_NAME --司机名称, CAR_LICENSE_NO --车辆编号, SHIPMENT_PLAN_ID --配送计划ID, VENDOR_ID --发货客户, SHIPMENT_PLAN_NO --运单号 )SELECT 'AHO' || SHIPMENT_ID --操作历史ID, SHIPMENT_ID --引用ID, 'OPERATOR_SHIPMENT_OCJ_IMPORT' --操作类型, 'AGAIN_OCJ_IMPORT' --, WAREHOUSE_ID --分拨中心, FROM_WAREHOUSE_ID --, '-' --库位, CREATE_DATE --开始时间, 'State_All_Y' --状态, '' --备注, CREATE_BY --创建者, CREATE_DATE --创建时间, CREATE_BY --最后修改者, CREATE_DATE --最后修改时间, DRIVER_NAME --司机名称, CAR_LICENSE_NO --车辆编号, '-' --配送计划ID, VENDOR_ID --发货客户, SHIPMENT_PLAN_NO --运单号FROM OCJ_SHIPMENT_TEMPWHERE SESSION_ID = P_SESSION_ID AND IS_REPEAT = 'YS_Yes';--覆盖导入END P1本文来自CSDN博客,转载请标明出处:/soft_luo/archive/2009/12/01/4915477.aspx。
DB2的存储过程调用例子
DB2的存储过程调用例子关键字: db2的存储过程调用例子语法说明1、procedure-name: 存储过程的名字,在同一个数据库的同一模式下,不能存在存储过程名相同参数数目相同的存储过程,即使参数的类型不同也不行。
leizhimin 51cto技术博客2、(IN | OUT | INOUT parameter-name data-type,...) :传入参数IN:输入参数OUT:输出参数INOUT:作为输入输出参数parameter-name:参数名字,在此存储过程中唯一的标识符。
data-type:参数类型,可以接收SQL类型和创建的表。
不支持LONG VARCHAR, LONG VARGRAPHIC, DATALINK, REFERENCE和用户自定义类型。
3、SPECIFIC specific-name:唯一的特定名称(别名),可以用存储过程名代替,这个特定名称用于dorp存储过程,或者给存储过程添加注视用,但不能调用存储过程。
如果不指定,则数据库会自动生成一个yymmddhhmmsshhn时间戳的名字。
推荐给出别名。
4、DYNAMIC RESULT SETS integer:指定存储过程返回结果的最大数量。
存储过程中虽然没有return语句,但是却能返回结果集。
5、CONTAINS SQL, READS SQL DATA, MODIFIES SQL DATA:指定存储过程中的SQL访问级别CONTAINS SQL:表示存储过程可以执行中,既不可读取SQL 数据,也不可修改 SQL 数据。
READS SQL DATA:表示存储过程可以执行中,可读取SQL,但不可修改 SQL 数据。
MODIFIES SQL DATA:表示存储过程可以执行任何 SQL 语句。
可以对数据库中的数据进行增加、删除和修改。
6、DETERMINISTIC or NOT DETERMINISTIC:表示存储过程是动态或者非动态的。
DB2(Procedure)存储过程遍历循环!
DB2(Procedure)存储过程遍历循环!作者博客地址更换⾄CSDN,地址:/littlebrain4solving由于有时候⼀些复杂的业务逻辑将要通过存储过程的循环语句进⾏处理;以下列出2种DB2存储过程的循环语句,⽅便以后的查看并使⽤!本⼈推荐第⼀种⽅式的使⽤,最⼤的优点就是⽐较直观;在需要操作很多字段的情况下,不需要定义太多的字段变量作为中间存储媒介.⼀.FOR⽅式(FOR .. AS [游标名] CURSOR FOR [SELECT......])BEGIN--语句块,必须要加上,否则会出错.FOR V AS MYCURSOR CURSOR FOR SELECT ID,NAME,AGE FROM PEOPLEDOBEGIN--这⾥进⾏业务逻辑处理,每⾏循环的时候,每列的值将会存放于V变量中--⽰例: 把数据插⼊到另外⼀张表INSERT INTO PERSON(NAME,AGE) VALUES(,V.AGE);END;END FOR;END;⼆.WHILE⽅式(DECLARE [游标名] CURSOR FOR [SELECT.....])BEGIN--语句块,必须要加上,否则会出错.DECLARE NOTFOUND INT DEFAULT0;DECLARE V_NAME VARCHAR(20);DECLARE V_AGE VARCHAR(20);DECLARE MYCURSOR CURSOR FOR SELECT NAME,AGE FROM PEOPLE;DECLARE CONTINUE HANDLER FOR NOT FOUND SET NOTFOUND =1;WHILE NOTFOUND =0 DO FETCH MYCURSOR INTO V_NAME,V_AGE --这⾥的顺序要与查询结果字段顺序⼀致--这⾥会多循环⼀次,所以需要加⼀个判断IF(NOTFOUND =0)THENINSERT INTO PERSON(NAME,AGE) VALUES(V_NAME,V_AGE);END IF;END WHILE;END;。
DB2存储过程
--CURSOR---------->
>--FOR--+-select-statement
-+-------------><
.-WITHOUT HOLD-.
|--+--------------+---------------------------------------------|
DB2 支持以下创建数组数据类型的语法:
清单 2. 创建数组数据类型的语法
Sql代码
>>-CREATE TYPE—array-type-name--AS--| data-type |--ARRAY--[---------->
.-2147483647-------.
若要更改默认函数路径,则需要更新专用寄存器 CURRENT PATH。
游标
声明
SQL PL 提供 DECLARE cursor 语句来定义一个游标,并提供其他语句来支持返回其他结果集和游标处理。
下面是游标声明的语法: Leabharlann 清单 7. 游标声明的语法
>>-DECLARE--cursor-name
现在可以在 SQL 过程中使用这个数据类型:
清单 3. 在过程中使用数组数据类型
Sql代码
CREATE PROCEDURE PROC_VARRAY_test (out mynames names)
BEGIN
DECLARE v_pnumb numbers;
'-WITH HOLD----'
.-WITHOUT RETURN-------------.
|--+----------------------------+-------------------------------|
java调用db2存储过程例子
java调用db2存储过程例子java调用db2存储过程例子1. JAVA 调用db2存储过程最简单的例子:存储过程创建代码:<o:p></o:p>sql 代码1.SET SCHEMA IES ;2.3.Create procedure ies.test()4.NGUAGE SQL6.7.Update t_ryxx set xm =’xy’ where ryxxid=’xm’java 代码1.conn = DbMaster.getConn();2.System.out.println("begin………");3.proc = conn.prepareCall("{call test()}");4.proc.execute();<o:p></o:p>2. Java调用db2带输入参数存储过程的例子:<o:p></o:p>Db2创建存储过程的代码:<o:p></o:p>sql 代码5.Drop procedure ies.test();6.SET SCHEMA IES ;7.Create procedure ies.test(in i_ryxxid varchar(50))NGUAGE SQL9.Update t_ryxx set xm =’xy’ where ryxxid=i_ryxxid10.java 代码11.conn = DbMaster.getConn();12.System.out.println("begin");13.proc = conn.prepareCall("{call test(?)}");14.proc.setString(1,"RY0003");15.proc.execute();16.System.out.println("end:");3.有输入输出参数的代码:创建存储过程的代码:sql 代码17.SET SCHEMA IES ;18.CREATE PROCEDURE IES.test (IN in_ryxxid varchar(50),out out_xm varchar(50))NGUAGE SQL20.21.select xm into out_xm from ies.t_ryxx where ryxxid=in_ryxxid;java 代码22.proc = conn.prepareCall("{ call test(?,?)}");23.proc.setString(1, "011900380103");24.proc.registerOutParameter(2, Types.VARCHAR);25.proc.execute();26.String xm = proc.getString(2);27.System.out.println("end:"+xm);4.带有游标的存储过程(不知道这里的游标什么时候close的。
DB2数据库SQL存储过程
DB2数据库SQL存储过程高性能的SQL过程是数据库开发人员所追求的,我将不断把学到的,或在实际开发中用到的一些提高SQL过程性能的技巧整理出来,温故而知新.1,在只使用一条语句即可做到时避免使用多条语句让我们从一个简单的编码技巧开始。
如下所示的单个 INSERT 行序列:INSERT INTO tab_comp VALUES (item1, price1, qty1);INSERT INTO tab_comp VALUES (item2, price2, qty2);INSERT INTO tab_comp VALUES (item3, price3, qty3);可以改写成:INSERT INTO tab_comp VALUES (item1, price1, qty1),(item2, price2, qty2),(item3, price3, qty3);执行这个多行 INSERT 语句所需时间大约是执行原来三条语句的三分之一。
孤立地看,这一改进看起来似乎是微乎其微的,但是,如果这一代码段是重复执行的(例如该代码段位于循环体或触发器体中),那么改进是非常显著的。
类似地,如下所示的 SET 语句序列:SET A = expr1;SET B = expr2;SET C = expr3;可以写成一条 VALUES 语句:VALUES expr1, expr2, expr3 INTO A, B, C;如果任何两条语句之间都没有相关性,那么这一转换保留了原始序列的语义。
为了说明这一点,请考虑:SET A = monthly_avg * 12;SET B = (A / 2) * correction_factor;将上面两条语句转换成:VALUES (monthly_avg * 12, (A / 2) * correction_factor) INTO A, B;不会保留原始的语义,因为是以“并行”方式对 INTO 关键字之前的表达式进行求值的。
使用ibmdatastudio开发调试db2存储过程
使用 ibm data studio 开发调试 db2 存储过程IBM Data Studio 是一款免费的基于 Eclipse 的用于数据库开发的工具。
IBM Data Studio 包含了开发数据库存储过程的所有功能,同时提供了对 DB2 v9 的 XML 功能的支持。
本文将通过一个开发实例介绍 IBM Data Studio 是如何帮助我们进行存储过程开发的。
项目实例介绍在开始使用 IBM Data Studio 之前,让我们先来了解一下本文的项目实例。
该项目实例是一个简化版的软件开发管理系统。
系统主要管理 User Story 和Work Item 的信息。
User Story 就是以用户的角度编写的业务需求,是软件需要实现的功能。
我们需要记录 User Story 的具体内容和其状态。
这里的状态是指该User Story 是在草拟状态还是完成状态。
Work Item 用于记录软件开发的过程。
Work Item 可以是根据某个 User Story 编写的详细设计,也可以是一个编码任务,或者是一个 bug 报告。
我们需要记录其状态(未分配,处理中和完成等),结对编程人员的 Email 等信息。
本系统应该实现如下功能 ( 未列出所有功能 ):创建 User Story 。
修改 User Story 。
查询所有草拟状态的 User Story 。
创建 Work Item 。
修改 Work Item 。
查询属于某个 User Story 的所有 Work Item 。
为此我们设计了相应的数据库表:USER_STORY 和 WORK_ITEM 。
它们的详细定义如下表所示: 图 1. User story 和 Work item 的关系表 1. User Story 的定义 USER_STORY 列名称类型说明id INTEGER 表主键。
author VARCHAR 编写人的 Email 地址。
DB2 中游标的使用以及 存储过程的写法
什么时候才会发生not found异常,以及db2中sqlcode的值是如何变化的?在db2中,一条select 语句也有可能发生not found异常,譬如declare sqlcode integer default 0;declare sql_code integer default 0;declare classCode varchar(40) ;select app_class_code into classCode from kf_app_class where app_name='无效记录';set sql_code=sqlcode;如果此时没有检索到记录,那么sqlcode的值为100,有的话为0;我们可以定义NOT FOUND 异常处理declare sqlcode integer default 0;declare sql_code integer default 0;declare classCode varchar(40) ;begindeclare continue handler for not foundbegin--注如果发生not found那么此时的sqlcode必定为100set sql_code=sqlcode;/*在这里sqlcode的值为100;*/--如果再次得到sqlcode的值那么它的值变为0set sql_code=sqlcode;/*这里sqlcode变成了0,因为上一条语句执行成功了,那么sqlcode变成了0*/end;select app_class_code into classCode from kf_app_class where app_name='无效记录';set sql_code=sqlcode;/*同理此时如果没有取到数据,那么会进declare continue handler ,返回后sqlcode的值也为0*/end;所以我们可以通过两种方法来捕获和处理not found方法1:begindeclare continue handler for not foundbegin--异常处理代码end;sql语句end;方法2:beginsql语句if sqlcode=100 then--异常处理代码end;问题2:定义了游标,怎么fecth一条记录,怎么进行循环?Q:定义了游标假设发生not found 异常,那么是在open cursorName的时候还是在fecth的时候发生异常?A:检验游标中的数据是否取完或者有无记录,应该在fecth的时候,而不是发生在open cursorName 的时候,下面一个例子详细的说明了游标使用过程begindeclare sqlcode integer default 0;declare app_code varchar(10);declare cursor1 cursor for select app_code from kf_app_class ;open cursor1;cursorLoop:loopfecth cursor1 into app_code ;if sqlcode=100 then leave cursorLoop;end if;end loop;end;Q:sqlcode 可以直接用吗?A:在db2中,如果要使用sqlcode那么必须在使用前declare;譬如declare sqlcode integer default 0;if sqlcode =? thenend if;附注db2的其他异常处理对应oracle的when other exceptionsdeclare exit handler for sqlwaring,sqlexcptionbegin--处理异常end;当程序执行exit handler异常处理后,那么会退出程序,不会在接着执行,也就是declare exit handler for sqlwaring,sqlexcptionbegin--处理异常end;sql语句1;sql语句2;执行sql语句1发生异常,会进入exit handler ,然后退出程序,不会在执行sql语句2 执行sql语句1发生异常,会进入exit handler ,然后退出程序,不会在执行sql语句2。
db2数据库存储过程
-17-
模块 - 其他语句
删除整个模块
− DROP MODULE myMod;
保留规格说明内容,删除实现
− ALTER MODULE myMod DROP BODY;
删除模块中的存储过程(SP)
− ALTER MODULE myMod DROP PROCEDURE myProc;
将模块的执行权限赋给joe
ITERATE FETCH_LOOP1;
END IF; INSERT INTO department(deptno, deptname, admdept) VALUES(‘NEW’, v_deptname, v_admdept); END LOOP FETCH_LOOP1;
-27-
GOTO语句
GOTO语句用于直接跳转到指定标签处。例如: IF v_DEPT = ‘D11’ GOTO bye; ……
DECLARE my_var INTEGER DEFAULT 6;
条件声明
DECLARE not_found CONDITION FOR SQLSTATE ‘02000’;
游标声明
DECLARE c1 CURSOR FOR select * from staff;
异常处理器声明
DECLARE EXIT HANDLER FOR SQLEXCEPTION …;
(DECLARE关键字,cl游标名称, CURSOR是必须有的,;指通过c1的游标来操作staff里所有的数据)最常用的最普 通的。
2.DECLARE c1 CURSOR WITH HOLD FOR select * form staff; 3.DECLARE c1 CURSOR WITH RETURN TO CALLER FOR select * form staff; 4.DECLARE c1 CURSOR WITH RETURN TO CLIENT FOR select * form staff;
DB2存储过程语法规则
DB2存储过程语法规则如何声明⼀个存储过程CREATE PROCEDURE 存储过程名(IN 输⼊变量名输⼊变量类型,OUT 输出变量名输出变量类型)紧跟其后的是存储过程属性列表常⽤的有:LANGUAGE SQL、MODIFIES SQL DATA、RESULT SETS 1(返回结果集个数) l 存储过程体以begin开始l 存储过程体以end结束存储过程约束规则存储过程中调⽤存储过程CALL 存储过程名(参数1,参数2,参数n)例:call spco_init_custom(bankcode,errno,errmsg);GET DIAGNOSTICS retval=RETURN_STATUS;if(retval<>0) thenset errno=errno;set errmsg=errmsg;return errno;end if;变量的定义变量使⽤前必须先定义,⽅法为DECLARE 变量名变量类型(default 默认值)例:DECLARE SQLCODE INTEGER DEFAULT 0;DECLARE inum INTEGER DEFAULT 0;DECLARE curtime char(8);DECLARE bcode char(6);DECLARE sqlstate char(5);if 表达式if 条件1 then逻辑体;elseif 条件2 then逻辑体;else逻辑体;end if;例:IF rating = 1 THENUPDATE employeeSET salary = salary * 1.10, bonus = 1000WHERE empno = employee_number;ELSEIF rating = 2 THENUPDATE employeeSET salary = salary * 1.05, bonus = 500WHERE empno = employee_number;ELSEUPDATE employeeSET salary = salary * 1.03, bonus = 0WHERE empno = employee_number;END IF;case表达式case 变量名 when变量值1 then. . .when变量值2 then- - -else. . .end case;或case when变量名=变量值1 then. . .when变量名=变量值2 then- - -else. . .end case;例⼀:CASE v_workdeptWHEN 'A00'THEN UPDATE departmentSET deptname = 'DATA ACCESS 1';WHEN 'B01'THEN UPDATE departmentSET deptname = 'DATA ACCESS 2';ELSE UPDATE departmentSET deptname = 'DATA ACCESS 3';END CASE;例⼆:CASEWHEN v_workdept = 'A00'THEN UPDATE departmentSET deptname = 'DATA ACCESS 1';WHEN v_workdept = 'B01'THEN UPDATE departmentSET deptname = 'DATA ACCESS 2';ELSE UPDATE departmentSET deptname = 'DATA ACCESS 3';END CASE;for 表达式for 循环名 as游标名或select 表达式dosql表达式;end for;例:1)DECLARE fullname CHAR(40);FOR vl ASSELECT firstnme, midinit, lastname FROM employee DOSET fullname = lastname || ',' || firstnme ||' ' || midinit; INSERT INTO tnames VALUE (fullname);END FOR2)for loopcs1 as cousor1 cursor asselect market_code as market_codefrom tb_market_codefor updatedoend for;goto表达式goto 标⽰名;标⽰名:逻辑体;例:GOTO FAIL;...SUCCESS: RETURN 0FAIL: RETURN -200while表达式while 条件表达式 do逻辑体;end while;LOOP表达式LOOP... END LOOP;例:OPEN c1;ins_loop:LOOPFETCH c1 INTO v_dept, v_deptname, v_admdept;IF at_end = 1 THENLEAVEins_loop; --中断循环ELSEIF v_dept = 'D11' THENITERATEins_loop; --下⼀个循环END IF;INSERT INTO department (deptno, deptname, admrdept)VALUES ('NEW', v_deptname, v_admdept);END LOOP;CLOSE c1;关于游标定义游标:DECLARE 游标名 CURSOR FORSelect 语句;打开游标:OPEN 游标名;取值: FETCH 游标名 INTO 变量列表例:DECLARE c1 CURSOR FORSELECT CAST(salary AS DOUBLE)FROM staffWHERE DEPT = deptNumberORDER BY salary;DECLARE EXIT HANDLER FOR NOT FOUNDSET medianSalary = 6666;SET medianSalary = 0;SELECT COUNT(*) INTO v_numRecordsFROM staffWHERE DEPT = deptNumber;OPEN c1;WHILE v_counter < (v_numRecords / 2 + 1) DOFETCH c1 INTO medianSalary;SET v_counter = v_counter + 1;END WHILE;CLOSE c1;注:游标的申明如果放在中间段,要⽤”begin。
DB2存储过程
FOR
举例说明: CREATE PROCEDURE names() LANGUAGE SQL BEGIN DECLARE fullname CHAR(140); FOR v1 AS SELECT firstnme, midinit, lastname FROM employee DO SET fullname = stname || ', ' || v1.firstnme ||' ' || v1.midinit; INSERT INTO tname VALUES (fullname); END FOR; END
游标使用
游标有两种类型:静态的和动态的。使用游标前要先定义,然后可以使用循环语句操 作游标。 定义游标: DECLARE 游标名 CURSOR FOR Select 语句; 打开游标: OPEN 游标名; 取值: FETCH 游标名 INTO 变量列表 关闭游标: Close 游标名; 举例说明:
变量定义
存储过程中可以使用关键字DECLARE定义变量,然后在后续程序过程中使用变量来 处理逻辑。定义变量时可以指定一个初始值。
举例说明:
DECLARE temp1 INT DEFAULT 0;
ห้องสมุดไป่ตู้赋值语句
存储过程使用关键字SET给变量赋值。
举例说明: SET total = 100; VALUES(100,200,200+1) INTO var1,var2,var3; /*并行赋值,效率高*/ SET total = NULL;
存储过程的优点 减少客户机与服务器之间的网络使用率。客户机应用程序 将控制权传送到数据库服务器上的存储过程。存储过程在 数据库服务器上执行中间处理,而不需要在网络中传送不 需要的数据。 提高安全性。通过使使用静态 SQL 的存储过程包含数据库 特权,数据库管理员(DBA)可以提高安全性。调用存储 过程的客户机应用程序的用户不需要数据库特权。 提高可靠性。在数据库应用程序环境中,许多任务是重复 的。通过重用一个公共过程,存储过程就可以高效地解决 这些重复情况。
调用存储过程
调用存储过程在java可以使用java.sql.CallableStatement 对象调用存储过程,并返回执行的结果集1.获取CallableStatement语句:CallableStatement cs = conn.prepareCall("{call spName(?,?,?)}");2.传入输入参数和注册输出参数cs.setXXX(index,value);//输入参数cs.registerOutParameter(index,type);//输出参数3.执行存储过程:cs.execute();调用存储过程的语句为{ call procedureName ( ?,?,?) }如果存在返回值(非游标){ ?= call procedureName ( ?,?,?) }返回的游标用getResultSet方法获得注意1. 在DB2中如果要返回游标,V8下的存储过程中一定要加入“DYNAMIC RESULT SETS 1”,否则不会得到记录集,在v7下反而没有这个问题。
2. 存储过程传入参数要根据不同的类型,调用不同的CallableStatement.Set语句,否则会出现类型转换错误3. 返回记录集还有另外一种方法:CallableStatement toesUp =db.joinConnection().prepareCall("{ ? = call callfunctionreturn() }");toesUp.registerOutParameter(1, Types.OTHER);toesUp.execute();ResultSet rs = (ResultSet) toesUp.getObject(1);这种方式在db2下“toesUp.registerOutParameter(1, Types.OTHER);”报错,db2无法转化结果集为OTHER类型,在oracle下倒是可以,但不能设置为Types.OTHER,要设置为oracle.jdbc.driver.OracleTypes.OTHER4.在db2下(又是db2)如果存储过程执行发生错误(如insert失败),即使在存储过程中有exception处理,调用仍然失败,报com.ibm.db2.jcc.b.DisconnectException #6548 The DDM object is not supported.Unsupported DDM object code point: 0x220c错误。
DB2存储过程
DB2 存储过程SQL Procedural Language简介DB2 SQL Procedural Language(SQL PL)是SQL Persistent Stored Module 语言标准的一个子集。
该标准结合了SQL 访问数据的方便性和编程语言的流控制。
通过SQL PL 当前的语句集合和语言特性,可以用SQL 开发综合的、高级的程序,例如函数、存储过程和触发器。
这样便可以将业务逻辑封装到易于维护的数据库对象中,从而提高数据库应用程序的性能。
SQL PL 支持本地和全局变量,包括声明和赋值,还支持条件语句和迭代语句、控制语句的转移、错误管理语句以及返回结果集的方法。
变量声明SQL 过程允许使用本地变量赋予和获取SQL 值,以支持所有SQL 逻辑。
在SQL 过程中,在代码中使用本地变量之前要先进行声明。
清单1 中的图演示了变量声明的语法:清单 1. 变量声明的语法SQL-variable-name定义本地变量的名称。
该名称不能与其他变量或参数名称相同,也不能与列名相同。
图1 显示了受支持的DB2 数据类型:图 1. DB2 数据类型DEFAULT值–如果没有指定,在声明时将赋值为NULL。
下面是变量声明的一些例子:∙DECLARE v_salary DEC(9,2) DEFAULT 0.0;∙DECLARE v_status char(3) DEFAULT ‘YES’;∙DECLARE v_descrition VARCHAR(80);∙DECLARE v1, v2 INT DEFAULT 0;请注意,从DB2 version 9.5 开始才支持在一个DECLARE 语句中声明多个相同数据类型的变量。
数组数据类型SQL 过程从9.5 版开始支持数组类型的变量和参数。
要定义一个数组类型的变量,需要先在数据库中创建该类型,然后在过程或应用程序中声明它。
数组是临时的值,可以在存储过程和应用程序中操纵它,但是不能将它存储到表中。
db2 存储过程调用
db2 存储过程调用DB2存储过程调用在数据库管理系统中,存储过程是一组预定义的SQL语句集合,可以被多次调用。
DB2是一种流行的关系型数据库管理系统,它提供了强大的存储过程功能,使得开发人员能够更好地组织和管理数据库操作。
存储过程的调用是通过执行特定的SQL语句来实现的。
在DB2中,存储过程可以接受参数,并返回结果。
通过使用存储过程,可以将复杂的业务逻辑封装在数据库中,提高数据库的性能和安全性。
要调用DB2存储过程,首先需要创建存储过程。
存储过程可以在DB2的命令行界面或者图形化界面中创建。
创建存储过程时,需要指定存储过程的名称、参数和SQL语句。
参数可以是输入参数、输出参数或者输入输出参数,用于传递数据给存储过程或者从存储过程中返回数据。
一旦存储过程创建完成,就可以通过执行CALL语句来调用存储过程。
CALL语句后面跟着存储过程的名称和参数。
参数可以是常量值,也可以是变量。
在调用存储过程之前,需要确保参数的值是正确的,并且与存储过程定义的参数类型匹配。
在调用存储过程之后,可以获取存储过程的执行结果。
如果存储过程定义了输出参数,可以通过引用这些参数来获取结果。
此外,存储过程还可以返回结果集,可以通过游标来处理这些结果集。
DB2存储过程调用的一个重要特性是事务处理。
在调用存储过程时,可以将其包含在一个事务中。
事务可以保证存储过程的原子性,即要么全部执行成功,要么全部回滚。
这对于处理复杂的数据库操作非常有用,可以确保数据的一致性和完整性。
除了通过SQL语句调用存储过程外,DB2还提供了其他方式来调用存储过程。
例如,可以使用Java程序或者其他编程语言来调用存储过程。
这些方式可以根据具体的应用需求来选择,以实现更灵活和高效的存储过程调用。
总结一下,DB2存储过程调用是一种强大的数据库操作方式,可以提高数据库的性能和安全性。
通过存储过程,可以将复杂的业务逻辑封装在数据库中,实现更好的代码复用和维护性。
DB2存储过程学习笔记
创建:db2-td@-vf createSQLproc.db2--end@ (此处的@可替换成其他符号)调用:db2call过程名(参数)1 基础--声明变量:DECLARE<variable-name><data-type><DEFAULT constant>--赋值:SET x=10;SET y=(SELECT SUM(c1)from T1);VALUES10INTO x;SELECT SUM(c1)INTO y from T1;--会话全局变量:CREATE VARIABLE var_name DATATYPE[DEAFULT value];2 、数组2.1定义CREATE TYPE mynames as VARCHAR(30)ARRAY[];--定义数组2.2声明DECLARE nameArr mynames;--声明数组2.3赋值SET TESTARR=ARRAY[1,2,3,4,5,6,7,8,9,10];SET TESTARR=ARRAY[VALU ES(1),(2)];--方法1,使用SET语句SELECT SUM(NUM)INTO TESTARR[1]FROM(VALUES(1),(2))AS TEMP(NU M);--方法2,使用VALUES INTO语句VALUES1INTO TESTARR[1];--方法3,使用SELECT INTO语句SET TESTARR[1]=1;--方法4,使用ARRAY构造函数2.4操作数组的函数ARRAY_DELETE:删除数组元素TRIM_ARRAY:从右开始删除指定数目个元素ARRAY_FIRST:返回数组中第一个元素ARRAY_LAST:返回数组中最后一个元素ARRAY_NEXT:返回数组下一个元素ARRAY_PRIOR:返回数组前一个元素ARRAY_VARIABLE:返回参数指定的元素ARRAY_EXISTS:判断数组是否有元素CARDINALITY:返回数组中元素的个数MAX_CARDINALITY:返回数组中元素的个数UNNEST:将数组转换为表3 复合语句语法:label:BEGIN[ATOMIC|NOT ATOMIC]--ATOMIC关键字封装的复合语句被当作一个处理单元--变量声明、过程逻辑等END label4流程控制--条件判断IFIF<condition>THEN<SQL procedure statement>;ELSEIF<condition>THEN<SQL procedure statement>;ELSE<SQL procedure statement>;END IF;IF FRIEND='张三'THENSET MSG='你好,张三';ELSEIF FRIEND='李四'THENSET MSG='你好,李四';ELSESET MSG='对不起,我不认识你';END IF;--循环WhileWHILE<condition>DO<sql statements>;END WHILE;WHILE I<=10DOSET NUM=NUM+I;SET I=I+1;END WHILE;--循环forFOR<loop_name>AS<sql statements>DO<sql statements>;END FOR;FOR TEST AS SELECT I FROM(VALUES(1),(2),(3))AS TEMP(I)DOSET NUM=NUM+I;END FOR;--循环LOOPLABEL:LOOP<sql statements>;LEAVE LABEL;END LOOP LABEL;TEST_LOOP:LOOPSET NUM=NUM+I;SET I=I+1;IF I>10THENLEAVE TEST_LOOP;END IF;END LOOP TEST_LOOP;--循环RepeatREPEAT<sql statements>;UNTIL<condition>END REPEAT;REPEATSET NUM=NUM+I;SET I=I+1;UNTIL I>10END REPEAT;--其他关键字ITERATE label--。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
db2 调用存储过程
摘要:
1.存储过程的定义与作用
2.DB2 数据库与存储过程的关系
3.DB2 调用存储过程的方法
4.调用存储过程的实例分析
5.存储过程的优点与使用注意事项
正文:
1.存储过程的定义与作用
存储过程是一组预编译的SQL 语句,用于执行特定的任务。
它可以接受输入参数,返回结果集,还可以输出参数。
存储过程在数据库中具有很高的性能,因为它们是预编译的,所以执行速度较快。
此外,存储过程有助于实现数据安全性和保持数据一致性。
2.DB2 数据库与存储过程的关系
DB2 是一种关系型数据库管理系统,它支持存储过程的编写和调用。
在DB2 中,存储过程可以用于执行复杂的业务逻辑、数据处理和数据操纵。
通过使用存储过程,可以简化应用程序的开发和维护,提高系统的性能和安全性。
3.DB2 调用存储过程的方法
在DB2 中,可以通过以下几种方法调用存储过程:
(1)使用CALL 语句:CALL 语句是DB2 中调用存储过程的常用方法。
它可以接受参数并将结果返回给调用者。
例如:CALL usp_name
(param1, param2,...)。
(2)使用EXECUTE IMMEDIATE 语句:EXECUTE IMMEDIATE 语句用于执行一条SQL 语句。
它可以用于调用存储过程,但需要将存储过程的定义文本作为参数传递。
例如:EXECUTE IMMEDIATE "CALL usp_name (param1, param2,...)";。
(3)使用DB2 Command Line Processor:通过DB2 Command Line Processor,可以直接输入CALL 语句调用存储过程。
例如:db2 -x "CALL usp_name (param1, param2,...)"。
4.调用存储过程的实例分析
假设有一个名为“get_employee_count”的存储过程,它用于查询员工表中的员工数量。
可以使用如下CALL 语句调用该存储过程:
```
CALL get_employee_count (emp_id);
```
该语句将返回查询结果,可以通过输出参数接收。
5.存储过程的优点与使用注意事项
存储过程具有以下优点:
(1)性能高:存储过程是预编译的SQL 语句,执行速度较快。
(2)安全性强:存储过程可以实现数据安全,防止非法访问和操作。
(3)易于维护:存储过程可以封装复杂的业务逻辑,简化应用程序的开发和维护。
在使用存储过程时,应注意以下几点:
(1)避免使用SELECT 语句:在存储过程中,应避免使用SELECT 语句查询数据,因为这会导致结果集无法传递给调用者。
(2)合理使用输出参数:存储过程可以返回结果集,但需要使用输出参数接收。
在调用存储过程时,应确保正确设置输出参数。