SYBASE数据库迁移到AS 400 db2的FAQ

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;

 

 

 

文章转自百度文库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值