SYBASE数据库迁移到AS 400 db2的FAQ
1.Sybase数据类型和db2有那些不同?
答:Datetime 对应 timestamp
Tinyint ,smallint 对应 smallint
Money 类型对应 numeric(19,4)
2.db2数据库是否支持自增加列设置?
答:支持,例如:SYSID BIGINT GENERATED ALWAYS AS IDENTITY
将原来sysid 的 numerical(18,0) 改为 BIGINT类型
3.Db2是否有convert()函数,sybase 下这样语句如何转换?
答:convert(datetime,convert(char(8),dateadd(day,-1,getdate()),112))
db2下没有convert()函数,关于转换可以使用如下函数
char(),timestamp(),date(),time() …另外可以使用系统内部的系统变量
current timestamp , current date , currenttime 代表系统当前日期时间
如上语句可以这样转换
timestamp( current date –1days,time(’00.00.00’))
4.Sybase的isnull(@vc_pici_id,’0’) 如何转换?
答:DB2下使用value(vc_pici_id,’0’)或者coalesce(vc_pici_id,’0’)
5.Db2下如何调用存储过程和调用代返回值得存储过程?
答: (1)无返回参数调用CALL proc1(v_empno, v_salary)
(2)有返回参数调用
declare ret_var integer default 0;
CALL proc1(var1,var2) ;
Get Diagnostics ret_var = RETURN_STATUS;
---------
declare err_code integer default 0;
call proc1(var1,err_code);
IF ERR_CODE = 1 THEN
XXXX;
END IF;
6.Sybase 下游标控制是非常方便的,使用sqlcode,sqlstate来控制,不知道db2下游标是如何控制的?
答:DB2下游标控制不是非常的轻松和方便的,同样也可以使用sqlcode,sqlstate,或者用户自己控制,DB2下SQLCODE,SQLSTATE不能直接使用,必须声明后使用,(也就是说将系统的SQLCODE,SQLSTATE本地实例化一分拷贝)。一般采用用户定义游标开关和sqlcode返回信息一起共同控制的方法.
举例1:(这里说明一个问题,游标开关是和SQLCODE捆绑的。‘02000’就是SQLCODE号)
//-------
标准使用游标的例子
标准WHILE DO 控制游标
//-------
CREATE PROCEDURE CREDITP
(IN i_perinc DECIMAL(3,2),
INOUT o_numrec DECIMAL(5,0))
LANGUAGE SQL
BEGIN -- 这里是用户管理事务
DECLARE proc_cusnbr CHAR(5);
DECLARE proc_cuscrd DECIMAL(11,2);
DECLARE numrec DECIMAL(5,0);
DECLARE at_end INT DEFAULT 0; -- 开关定义
DECLARE not_found CONDITION FOR '02000'; --没有数据,游标结尾定义
DECLARE c1 CURSOR FOR SELECT cusnbr, cuscrdFROM ordapplib.customer;
DECLARE CONTINUE HANDLER FOR not_found SETat_end = 1; --定义CONTINUE 条件
DECLARE EXIT HANDLER FOR SQLEXCEPTIONROLLBACK ; --sqlcode 非'01''00''02'则退出并回滚事务
SET numrec = 0;
OPEN c1;
FETCH c1 INTO proc_cusnbr, proc_cuscrd;
WHILE at_end = 0 DO
SET proc_cuscrd = proc_cuscrd +(proc_cuscrd* i_perinc);
SET numrec = numrec + 1;
FETCH c1 INTO proc_cusnbr, proc_cuscrd;
END WHILE;
SET o_numrec = numrec;
CLOSE c1;
COMMIT; --提交事务
END
举例2:
--声明游标C1
DECLARE c1 CURSOR FOR
SELECT cusnbr, cuscrd
FROM ordapplib.customer;
OPEN c1; --打开游标
FETCH c1 INTO proc_cusnbr, proc_cuscrd; --从游标获取数据
IF SQLSTATE = '02000' THEN --判断游标是否有数据(无)
CALL DATA_NOT_FOUND; --返回调用
ELSE
DO WHILE (SUBSTR(SQLSTATE,1,2) = '00' |SUBSTR(SQLSTATE,1,2) = '01');
FETCH c1 INTO proc_cusnbr, proc_cuscrd;
......
END IF ;
CLOSE c1; --关闭游标
7.DB2存储过程的标准格式如何?
答:DB2存储过程的编写比较灵活,但是语法格式是非常严格的。基本如下
CTEATE PROCEDURE XHZQ_DB.PROCNAME (
IN PARA_1 TYPE DEFAULT VALUE ,
OUT PARA_2 TYPE DEFAULT VALUE)
BEGIN ( 用户管理事务)
--用户定义变量
DECLARE VAR1 TYPE DEFAULT VALUE;
--用户定义控制临时变量
DECLARE ERROR_CODE INT DEFAULT 0;
DECLARE AT_END INT DEFAULT 0;
-- 用户定义条件控制变量
DECLARE not_found CONDITION FOR '02000';
-- 用户定义游标
DECLARE C1 CURSOR FOR SELECT COL FROM TABLE_NAME;
-- 用户定义条件和开关变量关联
DECLARE CONTINUE HANDLER FOR not_found SETat_end = 1;
-- 用户定义事务回滚处理条件
DECLARE EXIT HANDLER FOR SQLEXCEPTIONROLLBACK ;
-- 初始化变量直
SET VAR = 0;
-- 判断入口参数
IF (PARA_1 IS NULL) THEN
SET PARA = 100;
END IF;
-- 存储过程语句体集合
OPEN C1 ;
FETCH C1 INTO XX,XX2,XX3 ;
….
CLOSE C1;
-- 提交事务
COMMIT WORK HOLD;
SET PARA_2 = 0 ;
RETURN PARA_2 ;
-- 返回参数0 成功
END
8.Db2下char()函数用法
答: CHAR(DATE,Keyword) , CHAR(TIME,Keyword)
Keyword Date FormatTime Format
USA 07/17/2001 01:48PM
ISO 2001-07-17 13.48.04
EUR 17.07.2001 13.48.04
JIS 2001-07-17 13.48.04
9.如果是单字符,如“’”如何组合拼接?
答:同样可以使用CHAR(),进行ASCii 转换
例如:DECLARE VC_CHAR CHAR(1);
DECLARE VC_TEMP CHAR(10);
SET VC_CHAR = CHAR(39); -- 39 IS ‘ ASCii
10.Db2如何创建约束?
答:语法如下:ALTER TABLE XHZQ.INFO_SKU_TAB
ADD CONSTRAINTXHZQ.CKC_C_DIANZICHENG_FLA_INFO_SKU
CHECK( C_DIANZICHENG_FLAG IN ( '0' , '1' ,'2' ) ) ;
11.Db2下如何创建索引?
答:CREATE UNIQUE INDEX UNIQUE_NAME ON PROJECT (PROJNAME)
CREATE INDEX JOB_BY_DPT ON EMPLOYEE(WORKDEPT, JOB)
12.Sybase 中的全局变量@@rowcount,db2中如何使用?
答:db2中也有此全局变量,具体使用如下:
通过声明变量tempCount,使用语句
DECLARE TEMPCOUNT BIGINT DEFAULT = 0;
GET DIAGNOSTICS tempCount = ROW_COUNT;
获得,DB2下的ROW_COUNT等价于@@rowcount
13.DB2是如何管理事务的?
答:DB2中事务管理,也是支持自动事务管理和用户管理事务。
CREATE PROCEDURE XXX.PROC_NAME
( 。。。。。。。)
BEGIN AUTMIC --系统自动管理事务
END
BEGIN
如果系统自动管理事务,脚本中不允许出现COMMIT, ROLLBACK ,
使用这种方式,如果使用捆绑SQLCODE,SQLSTATE和游标,可以达到系统自动控制游标的功能。
IF (XX) THEN
COMMIT WORK HOLD;
ELSE
ROLLBACK WORK HOLD;
END IF;
END
14.DB2的VARCHAR()函数用法?
答:VARCHAR(Par,length)功能,将par转换为变长字符串
par : 参数character, integer , decimal , numeric, float,graph
length: 参数字符串长度
例如:SELECT VARCHAR(EMPNO,10)
INTO :VARHV
FROM EMPLOYEE
15.Db2的SING()函数用法?
答:sing(par) 功能判断par的大小和零比较
如果par < 0 返回 –1
如果par > 0 返回 1
如果par = 0 返回 0
例如:SELECT SIGN(ROFIT)
FROM EMPLOYEE
16.DB2如何创建用户自定义函数?
答:给出例子如下
/*
function name to_char
argument: (in) timestamp, format
comm:将日期转换为制定的字符格式
ruturn:制定格式的字符串
author: Dekker date: 2003-09-12
*/
CREATE FUNCTION xhzq_db.to_char ( t1TIMESTAMP, format VARCHAR(32) )
RETURNS VARCHAR(26)
LANGUAGE SQL
READS SQL DATA
NO EXTERNAL ACTION
BEGIN
DECLARE chs_tmstmp CHAR( 26 );
DECLARE retval VARCHAR( 26 );
SET chs_tmstmp = CHAR( t1 );
CASE TRIM(format)
WHEN 'DD'
THEN SET RETVAL = SUBSTR( chs_tmstmp, 9,2);
WHEN 'MM'
THEN SET RETVAL = SUBSTR( chs_tmstmp, 6,2);
WHEN 'YYYY'
THEN SET RETVAL = SUBSTR( chs_tmstmp, 1,4);
WHEN 'YYYY-MM-DD'
THEN SET RETVAL = SUBSTR( chs_tmstmp, 1,10);
ELSE SIGNAL SQLSTATE '38Z01'
SET MESSAGE_TEXT = 'INVALID FORMATSPECIFIED.';
END CASE;
RETURN retval;
END;
17.Sybase 中使用Getdate()获得当前日期时间,DB2时如何获得?
答:Now(),
VALUES CURRENT DATE;
VALUES CURRENT TIME;
VALUES CURRENT TIMESTAMP;
18.Db2的在线帮助网址是什么?
答http://publib.boulder.ibm.com/is ... /rbafzmsthctabl.htm
19.Db2中SQLSTATE的代号如何定义?
答:如下
Class Code 00: Unqualified SuccessfulCompletion
Class Code 01: Warning
Class Code 02: No Data
Class Code 07: Dynamic SQL Error
Class Code 08: Connection Exception
Class Code 09: Triggered Action Exception
Class Code 0A: Feature Not Supported
Class Code 0E: Invalid Schema Name ListSpecification
Class Code 0F: Invalid Token
Class Code 0K: Resignal When Handler NotActive
Class Code 20: Case Not Found for CaseStatement
Class Code 21: Cardinality Violation
Class Code 22: Data Exception
Class Code 23: Constraint Violation
Class Code 24: Invalid Cursor State
Class Code 25: Invalid Transaction State
Class Code 26: Invalid SQL StatementIdentifier
Class Code 27: Triggered Data ChangeViolation
Class Code 28: Invalid AuthorizationSpecification
Class Code 2D: Invalid TransactionTermination
Class Code 2E: Invalid Connection Name
Class Code 2F: SQL Function Exception
Class Code 34: Invalid Cursor Name
Class Code 38: External Function Exception
Class Code 39: External Function CallException
Class Code 3B: Savepoint Exception
Class Code 3C: Ambiguous Cursor Name
Class Code 42: Syntax Error or Access RuleViolation
Class Code 44: WITH CHECK OPTION Violation
Class Code 46: Java Errors
Class Code 51: Invalid Application State
Class Code 54: SQL or Product LimitExceeded
Class Code 55: Object Not in PrerequisiteState
Class Code 56: Miscellaneous SQL or ProductError
Class Code 57: Resource Not Available orOperator Intervention
Class Code 58: System Error
20.如何对当前游标的行数据进行删除,更新操作?
答:例如 DECLARE THISEMP CURSOR FOR SELECT EMPNO, LASTNAME,
WORKDEPT, JOB
FROM CORPDATA.EMPLOYEE
FOR UPDATE OF JOB ;
open THISEMP ;
…
UPDATE CORPDATA.EMPLOYEE
SET JOB = :NEW-CODE
WHERE CURRENT OF THISEMP
…
21.Db2中使用 NOT FOUND 控制游标?
答:NOT FOUND是DB2中的全局变量,可以等同于如下
IF SQLCODE =100 GO TO DATA-NOT-FOUND.
or
EXEC SQL
WHENEVER NOT FOUND GO TO symbolic-address
END-EXEC.
IF SQLSTATE ='02000' GO TO DATA-NOT-FOUND.
22.DB2下动态游标如何定义和使用?
答:给出一个例子
CREATE PROCEDURE CREATE_DEPT_TABLE (INP_DEPT CHAR(3))
LANGUAGE SQL
BEGIN
DECLARE STMT CHAR(1000);
DECLARE MESSAGE CHAR(20);
DECLARE TABLE_NAME CHAR(30);
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET MESSAGE = 'ok';
SET TABLE_NAME = 'CORPDATA.DEPT_' CONCATP_DEPT CONCAT '_T';
SET STMT = 'DROP TABLE ' CONCAT TABLE_NAME;
PREPARE S1 FROM STMT;
EXECUTE S1;
SET STMT = 'CREATE TABLE ' CONCATTABLE_NAME CONCAT
'( EMPNO CHAR(6) NOT NULL,
FIRSTNME VARCHAR(12) NOT NULL,
MIDINIT CHAR(1) NOT NULL,
LASTNAME CHAR(15) NOT NULL,
SALARY DECIMAL(9,2))';
PREPARE S2 FROM STMT;
EXECUTE S2;
SET STMT = 'INSERT INTO ' CONCAT TABLE_NAMECONCAT
'SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME,SALARY
FROM CORPDATA.EMPLOYEE
WHERE WORKDEPT = ?';
PREPARE S3 FROM STMT;
EXECUTE S3 USING P_DEPT;
END;
23.DB2下在存储过程中,直接执行sql语句,如何定义和使用?
答:举例如下
CREATE PROCEDURE CREATE_DEPT_TABLE (INP_DEPT CHAR(3))
LANGUAGE SQL
BEGIN
DECLARE STMT CHAR(1000);
DECLARE MESSAGE CHAR(20);
DECLARE TABLE_NAME CHAR(30);
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET MESSAGE = 'ok';
SET TABLE_NAME = 'CORPDATA.DEPT_' CONCATP_DEPT CONCAT '_T';
SET STMT = 'DROP TABLE ' CONCAT TABLE_NAME;
PREPARE S1 FROM STMT;
EXECUTE S1;
SET STMT = 'CREATE TABLE ' CONCATTABLE_NAME CONCAT
'( EMPNO CHAR(6) NOT NULL,
FIRSTNME VARCHAR(12) NOT NULL,
MIDINIT CHAR(1) NOT NULL,
LASTNAME CHAR(15) NOT NULL,
SALARY DECIMAL(9,2))';
PREPARE S2 FROM STMT;
EXECUTE S2;
SET STMT = 'INSERT INTO ' CONCAT TABLE_NAMECONCAT
'SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME,SALARY
FROM CORPDATA.EMPLOYEE
WHERE WORKDEPT = ?';
PREPARE S3 FROM STMT;
EXECUTE S3 USING P_DEPT;
END;
24.DB2是否支持多重事务?是如何实现的?
答: DB2支持多重事务,使用SAVEPOINT的机制管理多重事务处理。允许在一个事务中设置多个保存点,而出错是回滚到指定保存点。
COMMIT
ROLLBACK
SET TRANSACTION
SAVEPOINT STOP_HERE ON ROLLBACK RETAINCURSORS;
SAVEPOINT START_OVER UNIQUE ON ROLLBACKRETAIN CURSORS;
RELEASE SAVEPOINT START_OVER
25.Sybase 使用raiserror 99999 ‘xxxx’自定义错误信息,db2如何实现自定义错误?
答:使用signal SQLSTATE 'ii0002' set message_text = ‘dddd’; 指定SQLSTATE信息返回自定义的错误信息。注意sqlstate 必须是 5 位字符,可以是 0 – 9 ,不允许大写字符A-Z和其他特殊字符。不允许前两个字符是‘00’。Message_text 信息限制在70字节长度。
举例如下
CREATE PROCEDURE raise ( IN rating INTEGER)
LANGUAGE SQL
BEGIN
DECLARE new_salary DECIMAL(9,2);
DECLARE service DECIMAL(8,0);
DECLARE v_empno CHAR(6) DEFAULT '123456';
SELECT salary, current_date - hiredate
INTO new_salary, service
FROM employee
WHERE empno = v_empno;
IF service < 600
THEN SIGNAL SQLSTATE 'II001'
SET MESSAGE_TEXT = 'Insufficient time inservice.';
END IF;
IF rating = 1
THEN SET new_salary =
new_salary + (new_salary * .10);
ELSEIF rating = 2
THEN SET new_salary =
new_salary + (new_salary * .05);
END IF;
UPDATE employee
SET salary = new_salary
WHERE empno = v_empno;
END;
26.Db2中return的限制和使用?
答: return 不允许在触发器中使用。
27.Db2中如何创建trigger?
答:Db2的trigger 和Sybase 的触发器有些区别,Sybase中触发器全部市after方式。
Db2可以定义触发器的触发时机(after,before)
具体格式:
create Trigger info_plu_ti after insert oninfo_plu_tab Referencing New as new for each row
28.Db2的CASE 控制语句用法和例子?
答:用法举例如下:
CASE evaluation
WHEN 100 THEN UPDATE employee SET salary =salary * 1.3;
WHEN 90 THEN UPDATE employee SET salary =salary * 1.2;
WHEN 80 THEN UPDATE employee SET salary =salary * 1.1;
ELSE UPDATE employee SET salary = salary *1.05;
END CASE;
或者:
CASE
WHEN evaluation = 100 THEN UPDATE employeeSET salary = salary * 1.3;
WHEN evaluation = 90 THEN UPDATE employeeSET salary = salary * 1.2;
WHEN evaluation = 80 THEN UPDATE employee SETsalary = salary * 1.1;
ELSE UPDATE employee SET salary = salary *1.05;
END CASE;
29.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;
30.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;
31.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;
32.Db2的循环控制语句for用法?
答:for 例子
FOR each_record AS
cursor1 CURSOR FOR
SELECT cusnbr, cuscrd FROMordapplib.customer
DO
UPDATE ordapplib.customer
SET cuscrd = cuscrd * 1.1
WHERE CURRENT OF cursor1;
END FOR;
33.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;
34.在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 DYNAMIC 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 thecall statement:
EXEC SQL
CALL MYMAX( :fld_name, :file_name,:max_value :ind3);
35.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 ISNOT 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 FROMdepartment WHERE mgrno IS NOT NULL);
EXECUTE s1;
等同于
EXECUTE IMMEDIATE ‘UPDATE employee SETsalary = salary * 1.1 WHERE
empno IN (SELECT DISTINCT mgrno FROMdepartment WHERE mgrno IS NOT NULL);
最基本动态游标语句
...
DECLARE stmt VARCHAR[256];
...
SET stmt = ‘SELECT COLUMN1, COLUMN2,COLUMN3 FROM TBL1’;
PREPARE PreparedStatement FROM s1;
DECLARE Cursor1 CURSOR FORPreparedStatement;
...
36.Db2下支持返回结果集合的存储过程吗?
答:支持,例子1
CREATE PROCEDURE GetCusName()
RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE c1 CURSOR WITH RETURN FOR
SELECT cusnam FROM customer ORDER BYcusnam;
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
37.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四种。
38.某些SQL语句可能非常复杂,比如嵌套调用多个表或触发许多触发器,在对这样的SQL语句进行编译时,出现SQL0101N错误,如何处理
答:对于一个复杂的SQL语句,在调用多个表或触发多个触发器时, 可能会占用
大量的系统资源.
当出现SQL0101N错误时, 首先需要确认系统中没有递归的触发器存在.
之后可通过增加如下参数的值来解决此问题:
1)STMTHEAP
2)APPLHEAPSZ
3)PCKCACHESZ
39.如何实施联机备份?
答:数据库建立时日志方式默认是循环日志模式(Circular Log),这时是无法做联机备份的。所以,希望实施联机备份,首先要将日志方式改为归档日志模式(Archival Log)。
以sample数据库为例,可以在控制中心中改变sample数据库的配置参数LOGRETAIN为Recovery,或在命令行下用 db2 update db cfg for sample using LOGRETAIN on。改变此参数后,再次连接数据库会显示数据库处于备份暂挂(BACKUPPENDING)状态。这时,需要做一次对数据库的脱机备份。在控制中心中选择对数据库进行脱机备份或在命令行下用 db2 backup db sample 实施。此后数据库就可以进行联机备份了。
可以选择在控制中心中对数据库进行联机备份,或在命令行下用 db2 backup db sample online 实施。
注意: 利用联机备份得到的IMAGE文件进行恢复时,还需要相关的日志文件。
40.quiesce是一种持续状态的锁,它属于一个连接,当该连接失败时,quiesce状态依然存在。如何将表空间的状态置为正常状态?
答:除去quiesce状态:
1. 连接到数据库
2. 用 list tablespaces 判断哪个tablespace处于quiesce状态和和取得对象(object)ID
3. 判断对象ID对应的表
用 db2 "select tabname from syscat.tables where tablid=对象ID" 得到表名
b)用 db2 list history 判断是那个表
4. 用 db2 quiesce tablespaces for table 表名 reset 去除quiesce状态
41.在DB2 UDB中如何创建用户定义临时表?
答:可使用 DECLARE GLOBAL TEMPORARY TABLE 语句来定义临时表。此语句需在应用程序中使用。只有在应用程序与数据库断开连接之前,用户定义临时表才是持续的。
此表的说明并不出现在系统目录中,使其对于其他应用程序而言不是持续的,也不能与其他应用程序共享此表。
当使用此表的应用程序终止或与数据库断开连接时,此表中的数据被删除,此表被隐式卸下。
下面是定义临时表的一个示例:
DECLARE GLOBAL TEMPORARY TABLE gbl_temp
LIKE empltabl
ON COMMIT DELETE ROWS
NOT LOGGED
IN usr_tbsp
此语句创建一个名为 gbl_temp 的用户临时表。定义此用户临时表所使用的列的名称和说明与 empltabl 的列的名称和说明完全相同。隐式定义只包括列名、数据类型、可为空特性和列缺省值属性。未定义所有其他列属性,包括唯一约束、外部关键字约束、触发器和索引。执行 COMMIT 操作时, 若未对该表打开 WITH HOLD 游标,则该表中的所有数据都被删除。不记录 对用户临时表所作的更改。用户临时表被放在指定的用户临时表空间中。此表空间必须存在,否则此表的声明将失败。
42.在使用IMPORT命令向数据库出入数据时,如何避免日志空间满错误?
答:在执行IMPORT命令时, 如果使用循环日志, 有时会出现日志满错误,
这时可用COMMITCOUNT参数来解决.
因为日志空间满往往是因为所有的日志均处于活动状态导致的.
而COMMIT执行后, 会释放所占据的资源, 其中包括日志 .
这样, 被当前事务使用的日志在COMMIT命令执行后, 即变成非活动状态了
43.怎么样检查数据库连接有关的错误?
答:以TCP/IP连接为例, 若连接失败,您可以检查下列项目:
A) 在服务器上: 1) db2comm 注册表值包括值 tcpip。
输入 db2set DB2COMM 命令, 以检查 db2comm 注册表值的设置。有关详情,请参考管理指南。
2) 正确地更新了 services 文件。
3) 在数据库管理程序配置文件中正确地更新了服务名 (svcename) 参数。
4) 安全服务已启动。输入 net start db2ntsecserver 命令(仅对于 Windows NT 服务器)。
5) 正确地创建并编目了数据库。
6) 数据库管理程序已停止并再次启动(在服务器上输入 db2stop 和 db2start 命令)。
* 如果在启动一个协议的连接管理程序时出现问题,则会出现警告信息,并将错误信息记录在db2diag.log 文件中。
B) 在客户机上: 1) 正确地更新了 services 和 hosts 文件(若使用过的话)。
2) 使用正确的主机名 (hostname) 或 IP 地址 (ip_address)编目了此节点。
3) 端口号必须匹配,或服务名必须映射为服务器上所用的端口号。
4) 在数据库目录中指定的节点名 (node_name) 指向节点目录中的正确项目。
5) 数据库已正确编目, 它使用在服务器上创建该数据库时编目的服务器的数据库别名(database_alias),作为客户机上的数据库名 (database_name)。
验证这些项目后,若连接仍失败,则参考 DB2 Troubleshooting Guide
44.一种可以绕开删除整个表操作时遇到交易日志已满的办法
答:以空文件为数据文件导入(IMPORT)并替换(REPLACE)目标表和删除(DELETE)表操作的对比
当用DELETE TABLE命令删除整个表中数据时,该操作会逐条删除表中记录,并记入活动的交易日志。当表中数据量很大时,如果活动的交易日志不够大,就会遇到交易日志已满的错误,并回滚日志。即使活动的交易日志足够大,删除数据量很大的表的操作也会占用很多时间。用以空文件为数据文件导入(IMPORT)并替换(REPLACE)表的办法可以解决这个问题。例如
IMPORT FROM /dev/null OF DEL REPLACE INTO 目标表名
这样交易日志只会记录下该条命令,并立即释放所占的空间,而不会像删除命令一样逐条扫描记录,这就类似于DROP掉该表再创建一个完全相同只是没有数据的表一样。对于属于DMS表空间的表来说,删除命令逐条扫描记录,所占的记录空间仍标记为该表所用,而不立即释放空间,需要用REORG命令才可以释放剩余空间。用 LIST TABLESPACE SHOW DETAIL 可以对比两条命令执行后表空间中的剩余空间的大小。
用LOAD命令加REPLACE参数可以达到类似IMPORT命令加REPLACE的效果,但是由于LOAD本身不记日志,所以对于可恢复的数据库,LOAD完成后建议马上做一下联机备份的,相比之下,IMPORT命令加REPLACE操作上比较简单一些。
45. 怎么样获取表结构以及索引的信息
答:您可以使用"describe" 命令:
(1) 显示关于SELECT语句的 SQLDA 信息;
(2) 显示表或视图的列信息;
(3) 显示表或视图的索引信息;
举例:1) 下面的例子用于描述 SELECT 语句:
db2 "describe select * fromstaff"
SQLDA Information
sqldaid : SQLDA sqldabc: 896 sqln: 20 sqld:7
Column Information
sqltype sqllen sqlname.data sqlname.length
--------------- ------ -----------------------------
500 SMALLINT 2 ID 2
449 VARCHAR 9 NAME 4
501 SMALLINT 2 DEPT 4
2) 下面的例子用于描述表结构:
db2 describe table user1.department
Table: USER1.DEPARTMENT
Column
name Type
schema Type
name Length Scale Nulls
--------- ------- ----------- -------------- ------
AREA SYSIBM SMALLINT 2 0 No
DEPT SYSIBM CHARACTER 3 0 No
DEPTNAME SYSIBM CHARACTER 20 0 YES
3) 下面的例子用于描述索引结构:
db2 describe indexes for tableuser1.department
Table: USER1.DEPARTMENT
Index
schema Index
name Unique
rule Number of
columns
------------ ---------- ----------------------------
USER1 IDX1 U 2
46.如何在Unix平台上启动DB2控制中心(Control Center)
答:再Unix平台上启动DB2控制中心需要一下几个步骤,以AIX操作系统为例:
1. 安装DB2时选择安装DB2控制中心(Control Center);
2. 以root账号登录,输入xhost +命令(每次重新启动Unix后需输入该条命令以启动控制中心);
3. 以DB2实例管理员账号登录,输入以下命令
a. db2jstrt
b. db2cc
这样,就启动了DB2控制中心(Control Center)。
#xhost +
#su - db2inst1
$db2jstrt
$db2cc
db2cc使用的是jdk118
export JAVA_HOME=/usr/jdk118
export PATH=/usr/jdk118/bin:$PATH
47.如何更改本地系统名称
答:首先,从控制中心(Control Center)中知道本地系统所在的原节点名。
然后退出控制中心,在命令行处理器中输入以下命令:
1. db2set db2system=新系统名
2. db2 terminate
3. db2 uncatalog node 原节点名
4. db2 terminate
重起控制中心,可以看到,本地系统名已更改。
DECLARE UNDO HANDLER FOR SQLEXCEPTION
SET errmsg = 'ERROR, ROLLBACK WAS ISSUED';
48.DB2SIGNAL 和 RESIGNAL的用法?
答:举例
CREATE PROCEDURE xhzq_db.G10()
LANGUAGE SQL
BEGIN
DECLARE c1 CONDITION FOR SQLSTATE '38001';
DECLARE CONTINUE HANDLER FOR C1
INSERT INTO XHZQ_DB.ZZ_RESULT(proc,res)VALUES ('exec of G10','EXIT handler fired');
INSERT INTO XHZQ_DB.ZZ_result(proc,res)VALUES ('exec of G10','START of Proc');
SIGNAL SQLSTATE '38001';
INSERT INTO XHZQ_DB.ZZ_result(proc,res)VALUES ('exec of G10','END of Proc');
END;
如果调用后,select * from XHZQ_DB.ZZ_result ;
结果如下:
proc res
exec of G10 START of Proc
exec of G10 EXIT handler fired
exec of G10 END of Proc
举例
CREATE PROCEDURE G11()
LANGUAGE SQL
BEGIN
DECLARE c1 CONDITION FOR SQLSTATE '38001';
INSERT INTO result(proc,res) VALUES ('execof G11','START of Proc');
SIGNAL SQLSTATE '38001'; /*the handler willbe fired by this statement*/
INSERT INTO result(proc,res) VALUES ('execof G11','END of Proc');
END;
如果调用后,select * from result ;
结果如下:
proc res
exec of G11 START of Proc
49.关于AS400DB2中存储中文的问题
答:AS400下db2存储中文作了特殊处理。
格式为 0e 开头+ 中文字符串 + 0f结尾,如果有中文和英文字符串混合的字符串,其中每个中文字符串都加0e和0f
例如: 中国 存储后 0e中国0f
AV中国制造KK湖南 存储后: AV0e中国制造0fKK0e湖南0f
注意:除了a-z,A-Z以外的字符全部按中文字符串同样处理。
50.SQLCODE的捆绑声明语句
答:
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT ’00000’;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTIONSET retcode=SQLCODE;
DECLARE CONTINUE HANDLER FOR SQLWARNING SETretcode=SQLCODE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SETretcode=SQLCODE;
文章转自百度文库。