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;

 

 

 

文章轉自百度文庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章