SYBASE 数据库迁移到AS 400 db2的FAQ(四)
发表于:2007-07-02来源:作者:点击数:
标签:
31.Db2的循环控制语句loop用法? 答:loop例子: OPEN c1; SET at_end = 0; SET numrec = 0; fetch_loop: 1 LOOP FETCH c1 INTO proc_cusnbr, proc_cuscrd; IF SQLCODE = 0 THEN SET proc_cuscrd = proc_cuscrd * 1.2; UPDATE ordapplib.customer SET cuscrd
31.Db2的循环控制语句loop用法?
答:loop例子:
OPEN c1;
SET at_end = 0;
SET numrec = 0;
fetch_loop: 1
LOOP
FETCH c1 INTO proc_cusnbr, proc_cuscrd;
IF SQLCODE = 0 THEN
SET proc_cuscrd = proc_cuscrd * 1.2;
UPDATE ordapplib.customer
SET cuscrd = proc_cuscrd
WHERE CURRENT OF c1;
SET numrec = numrec + 1;
ELSE
LEAVE fetch_loop; 2
END IF;
END LOOP fetch_loop; 3
CLOSE c1;
32.Db2的循环控制语句while用法?
答:while 例子:
OPEN c1;
SET at_end = 0;
SET numrec = 0;
WHILE at_end = 0 DO
FETCH c1 INTO proc_cusnbr, proc_cuscrd;
IF SQLCODE = 0 THEN
SET proc_cuscrd = proc_cuscrd * 1.2;
UPDATE ordapplib.customer
SET cuscrd = proc_cuscrd
WHERE CURRENT OF c1;
SET numrec = numrec + 1;
ELSE
SET at_end = 1;
END IF;
END WHILE;
CLOSE c1;
33.Db2的循环控制语句repeat用法?
答:repeat例子
SET numrec = 0;
fetch_loop:
REPEAT
FETCH c1 INTO proc_cusnbr, proc_cuscrd;
IF SQLCODE = 0 THEN
SET proc_cuscrd = proc_cuscrd * 1.2;
UPDATE ordapplib.customer
SET cuscrd = proc_cuscrd
WHERE CURRENT OF c1;
SET numrec = numrec + 1;
END IF;
UNTIL SQLCODE <> 0
END REPEAT fetch_loop;
34.Db2的循环控制语句for用法?
答:for 例子
FOR each_record AS
cursor1 CURSOR FOR
SELECT cusnbr, cuscrd FROM ordapplib.customer
DO
UPDATE ordapplib.customer
SET cuscrd = cuscrd * 1.1
WHERE CURRENT OF cursor1;
END FOR;
34.Sybase 中循环控制Break,Continue在Db2用法?
答:在db2中 Break 转换为leave lab, Continue 转换为ITERATE lab
等同于GOTO语句
举例如下:
============== leave 例子
OPEN c1;
SET at_end = 0;
SET numrec = 0;
fetch_loop: 1
LOOP
FETCH c1 INTO proc_cusnbr, proc_cuscrd;
IF SQLCODE = 0 THEN
SET proc_cuscrd = proc_cuscrd * 1.2;
UPDATE ordapplib.customer
SET cuscrd = proc_cuscrd
WHERE CURRENT OF c1;
SET numrec = numrec + 1;
ELSE
LEAVE fetch_loop; 2
END IF;
END LOOP fetch_loop;
CLOSE c1;
============ iterate 例子
BEGIN
OPEN c1;
ins_loop: 1
LOOP
FETCH c1 INTO v_dept, v_deptname, v_admdept;
IF at_end = 1 THEN
LEAVE ins_loop;
ELSEIF v_dept = @#D11@# THEN
ITERATE ins_loop; 2
END IF;
INSERT INTO sampledb02.deptnew (deptno, deptname, admrdept)
VALUES (v_dept, v_deptname, v_admdept);
END LOOP;
CLOSE c1;
END;
35.在Db2存储过程中使用滚动游标(scrollable cursor)?
答:例子
CREATE PROCEDURE MYMAX
( IN fld_name CHAR(30),
IN file_name CHAR(128),
INOUT max_value INTEGER)
LANGUAGE SQL
BEGIN atomic
DECLARE
sql_stmt CHAR(256);
DECLARE not_found
CONDITION FOR @#02000@#;
DECLARE c1 DYNA
MIC SCROLL CURSOR FOR s1; -- 声明动态滚动游标
DECLARE CONTINUE HANDLER FOR not_found
SET max_value = NULL;
SET sql_stmt = @#SELECT @# || fld_name || @# FROM @# || file_name ||
@# ORDER BY 1@#; --组合sql语句
PREPARE s1 FROM sql_stmt;
OPEN c1;
FETCH LAST FROM c1 INTO max_value; --转到最后行
CLOSE c1;
END
滚动游标的使
用例子:(rpg)
EXEC SQL BEGIN DECLARE SECTION;
char fld_name[ 30 ];
char file_name[ 128 ];
integer max_value;
short ind3;
EXEC SQL END DECLARE SECTION;
Then the indicator variable is used in the call statement:
EXEC SQL
CALL MYMAX( :fld_name, :file_name, :max_value :ind3);
36.db2中存储过程中使用动态游标(dynamic cursor)?
答:使用PREPARE , EXECUTE ,EXECUTE IMMEDIATE语句
例子:
CREATE PROCEDURE DYNSQLSAMPLE()
LANGUAGE SQL
BEGIN
DECLARE stmt VARCHAR(256);
SET stmt = @#UPDATE employee SET salary = salary * 1.1 WHERE empno = ?@#; 1
PREPARE s1 FROM stmt;
ins_loop:
FOR each_department AS
c1 CURSOR FOR
SELECT mgrno FROM department WHERE mgrno IS NOT NULL
DO
EXECUTE s1 USING mgrno;
END FOR;
END;
EXECUTE IMMEDIATE statement 例子:
PREPARE s1 FROM ‘UPDATE employee SET salary = salary * 1.1 WHERE
empno IN (SELECT DISTINCT mgrno FROM department WHERE mgrno IS NOT NULL);
EXECUTE s1;
等同于
EXECUTE IMMEDIATE ‘UPDATE employee SET salary = salary * 1.1 WHERE
empno IN (SELECT DISTINCT mgrno FROM department WHERE mgrno IS NOT NULL);
最基本动态游标语句
...
DECLARE stmt VARCHAR[256];
...
SET stmt = ‘SELECT COLUMN1, COLUMN2, COLUMN3 FROM TBL1’;
PREPARE PreparedStatement FROM s1;
DECLARE Cursor1 CURSOR FOR PreparedStatement;
...
37.Db2下支持返回结果集合的存储过程吗?
答:支持,例子1
CREATE PROCEDURE GetCusName()
RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE c1 CURSOR WITH RETURN FOR
SELECT cusnam FROM customer ORDER BY cusnam;
OPEN c1;
SET RESULT SETS CURSOR c1;
END
例子2
CREATE PROCEDURE GETRANKV4R5
(IN proc_year DECIMAL(4,0),
IN proc_month DECIMAL(2,0),
INOUT proc_rank INTEGER)
RESULT SETS 2 ---- 2 两个结果集
LANGUAGE SQL
BEGIN
...
DECLARE c1 DYNAMIC SCROLL CURSOR FOR s1;
DECLARE c2 DYNAMIC SCROLL CURSOR FOR s2;
...
SET RESULT SETS CURSOR c1, CURSOR c2;
END
38.DB2数据库中一个表的行长度、列数以及每页行数在表空间中的限制
答:在DB2数据库中一个表的每行长度、列数以及每页行数在表空间中的限制如下:
[平台] Windows 9x/NT/2000,
Unix, Linux
[版本] 6.x/7.x
表空间页面大小 表空间中行长度限制(bytes)表空间中列数限制 表空间中每页最大行数
4K 4005 500 255
8K 8101 1012 255
16K 16293 1012 255
32K 32677 1012 255
注:表空间页面大小只有4K,8K,16K,32K四种。
39.某些SQL语句可能非常复杂,比如嵌套调用多个表或触发许多触发器,在对这样的SQL语句进行编译时,出现SQL0101N错误,如何处理
答:对于一个复杂的SQL语句,在调用多个表或触发多个触发器时, 可能会占用
大量的系统资源.
当出现SQL0101N错误时, 首先需要确认系统中没有递归的触发器存在.
之后可通过增加如下参数的值来解决此问题:
1)STMTHEAP
2)APPLHEAPSZ
3)PCKCACHESZ
40.如何实施联机备份?
答:数据库建立时日志方式默认是循环日志模式(Circular Log),这时是无法做联机备份的。所以,希望实施联机备份,首先要将日志方式改为归档日志模式(Archival Log)。
以sample数据库为例,可以在控制中心中改变sample数据库的配置参数LOGRETAIN为Recovery,或在命令行下用 db2 update db cfg for sample using LOGRETAIN on。改变此参数后,再次连接数据库会显示数据库处于备份暂挂(BACKUP PENDING)状态。这时,需要做一次对数据库的脱机备份。在控制中心中选择对数据库进行脱机备份或在命令行下用 db2 backup db sample 实施。此后数据库就可以进行联机备份了。
可以选择在控制中心中对数据库进行联机备份,或在命令行下用 db2 backup db sample online 实施。
注意: 利用联机备份得到的IMAGE文件进行恢复时,还需要相关的日志文件。
qq:50839655
msn:dekker@hotmail.com
email:zhangtao@xhzq.com,dekker99@163.com
原文转自:http://www.ltesting.net