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;
文章轉自百度文庫。