DB2數據庫常見問題匯總
1.1 創建存儲過程時需要注意變量聲明的順序
創建存儲過程時,聲明變量順序不符合規范將提示:
SQL0104N An unexpected token "<variable declaration>" was found following "".
Expected tokens may include: "<SQL statement>". LINE NUMBER=11.
SQLSTATE=42601
解答:聲明變量、游標以及條件處理要有序進行;普通變量聲明在先,其次到游標的聲明,最后才能聲明condition handler。
1.11 因為死鎖或超時,所以當前事務已回滾。
當前事務因死鎖或超時而回滾,將提示:
SQL0911N The current transaction has been rolled back because of a deadlock or timeout. Reason code "2".
根據原因碼確定具體原因,原因碼如下:
2 由於死鎖而導致事務已回滾。
68 由於鎖定超時而導致事務已回滾。
72 因為存在與事務中所涉及的 DB2 Data Links Manager 有關的錯誤,所以事務已回滾。
常見原因碼為2、68。應用程序已回滾至上一次 COMMIT。
解答:為了幫助避免死鎖或鎖定超時,對長時間運行的應用程序或有可能遇到死鎖的應用程序頻繁發出 COMMIT 操作(若有可能的話)。並適當地增大鎖超時時間:db2 update db cfg using LOCKTIMEOUT 60(此處60秒為例)。
1.12 在客戶端查詢數據庫中文信息會產生亂碼
解答:在服務器端或客戶端將編碼類型設置為1208以支持中文:db2set DB2CODEPAGE=1208。
1.13 重啟動機器后,用於創建表空間的裸設備與邏輯卷掛接失效,數據庫無法使用,提示:SQL0290N Table space access is not allowed. SQLSTATE=55039
解答:按原來的對應關系重新將裸設備和邏輯卷掛接起來;或創建一個機器重啟時自動執行的腳本,將該腳本放在/etc/init.d目錄下,並在/etc/init.d/rcN.d(N為當前系統運行級別,使用runlevel或who –r獲得,不同系統命令不同)目錄下建一個硬連接。
1.14 編目時確保使用正確的服務端口號
若在編目時使用的服務端口號與通過db2 get dbm cfg | grep SVCENAME查看到不一致,那在連接節點或數據庫時,將出現如下提示信息:
db2inst1@osta1:~> db2 connect to l2cache
SQL30081N A communication error has been detected. Communication protocol
being used: "TCP/IP". Communication API being used: "SOCKETS". Location
where the error was detected: "10.71.122.196". Communication function
detecting the error: "connect". Protocol specific error code(s): "111", "*",
"*". SQLSTATE=08001
Administrator>db2 attach to L194 user db2inst1
輸入 db2inst1 的當前密碼:
SQL30081N 檢測到通信錯誤。正在使用的通信協議:"TCP/IP"。正在使用的通信API:
"SOCKETS"。檢測到錯誤的位置:"10.71.100.191"。檢測到錯誤的通信函數:"connect"。
協議特定的錯誤代碼:"10061"、"*"、"*"。 SQLSTATE=08001
解答:
1、 檢查網絡工作狀態是否良好;
2、 通過db2 get dbm cfg | grep SVCENAME查看服務端口號,確認編目時使用的這個服務名稱或端口號;並確定服務器端和客戶端在etc/services文件中對服務名稱、端口號和協議的配置一致;
3、 確定編目時使用的通信協議或etc/services文件中配置的通信協議跟服務器設置的一致(通過db2set DB2COMM查看服務器使用的通信協議);
4、 前面沒問題,再去看看日志/sqllib/db2dump/db2diag.log是否有異常提示信息,根據提示解決問題。
1.15 不能分配“應用程序支持層“堆
內存不足(系統中可用的調頁空間量或交換空間量或系統中可用的物理內存量),可能會導致問題,並提示如下錯誤信息:
SQL1221N The Application Support Layer heap cannot be allocated. SQLSTATE=57011
解答:確認有足夠的內存資源可用於滿足數據庫管理器和系統上正在運行其它程序的需求。通過db2 update dbm cfg using ASLHEAPSZ 40(單位為4KB)適當增大應用程序支持層堆大小,或在適當的地方,停止使用該系統的其它程序。注意修改管理器的配置后,一定要重新啟動實例,修改才能生效。
1.16 如何查看數據庫占用內存情況
解答:1、db2pd –memsets
1.17 如何查看DB2的進程
解答:使用db2_ps 可以確定db2是否正常啟動。
1.18 如何將數據庫運行的環境收集起來
解答:使用db2support ./ –d 數據庫名 –s 將數據庫環境及系統環境收集起來打成包,對於數據庫管理器出現嚴重錯誤的情況,可以將此包發送給IBM的技術支援分析。
1.19 如何擴大表空間的容量
解答:給表空間增加新的容器:alter tablespace <tablespacename> add (device ‘/dev/raw/raw110’ 頁數);我們可以通過list tablespaces show detail查看表空間大小是否增大了或通過list tablespace containers for 表空間ID可以查看到該表空間使用的裸設備。
1.20 數據庫實例用戶無法訪問裸設備
當數據庫實例用戶沒有權限訪問創建數據庫所用的裸設備時,數據庫將無法使用,並會提示:The system attempted to write to a read-only file. SQLSTATE=55009
解答:修改裸設備的歸屬屬性:chown db2inst1:db2grp1 /dev/raw/rawX(X為裸設備id)。
1.21 如何讓數據庫支持中文字符集
解答:在服務器端修改數據庫字符集以支持中文字符集:db2set db2codepage=1208。
1.22 如何查看節點目錄和數據庫目錄的信息
解答:使用db2 list node directory 可以查看到所有節點編目信息,使用db2 list db directory 可以查看到所有數據庫的編目信息。
1.23 db2 select * from …類似這樣含有特殊字符的語句在Linux/Unix平台下,執行總是提示錯誤,無法執行
解答:由於sql語句含有特殊字符,所以需要將sql語句加上雙引號。但在db2命令行下則不需要加。
1.24 如何獲取當前時間
解答:使用db2 "select current time from sysibm.sysdummy1" 可以查看到當前的時間。
2、db2mtrk –i –d –v
3、db2 get snapshot for all on 數據庫名 | more +/ Memory usage for database
4、db2 update db cfg using DFT_MON_BUFPOOL on永久打開Buffer pool監視開關,或通過db2 update monitor switches using bufferpools on 數據庫名臨時打開某個數據庫對Buffer pool監視的開關(通過db2 get monitor switches查看臨時開關),然后使用定期執行db2 get snapshot for bufferpools on 數據庫名,並觀察Buffer pool data logical reads、Buffer pool data physical reads,Buffer pool index logical reads、Buffer pool index physical reads字段來確定系統的數據與索引的頁面命中率。
1.25 如何統計某個模式的對象數,並避免在刪除數據庫對象時誤刪除其他模式的對象
解答:可以在select語句的where字句中增加對模式的限制:select * from tabname where tabschema = ‘大寫的模式名’ (前提是之前要對對象設置模式:set schema = ‘大寫的模式名’),在刪除某個模式的對象時,可以使用,類似此例的方法:drop procedure db2inst1.procname。
1.26 如何在命令行下查看錯誤代碼的說明
解答:使用db2 ? sqlcode 可以查看到相應錯誤碼的說明。如db2 ? sql01450n。
1.27 如何在一個存儲過程中調用另一個存儲過程
解答:在需要調用的地方,使用類似此例的方法及可:CALL xp_VerifyTables(i,nTableType,nVerifyTableResult,sError); 其中xp_VerifyTables為要調用的存儲過程名,其參數在調用之前一定要聲明,最好都進行初始化。
1.28 如果查詢結果的字段比較少,如何將每條紀錄的列在同一行,以增強可讀性
解答:使用substr(col,exp1,exp2)對查詢結果的各字段進行處理,如:db2 "select substr(procschema,1,15),substr(procname,1,25),create_time,valid from syscat.procedures"。exp1為輸出字段col顯示的起始位置,exp2為col顯示的長度。
1.29 如果認為某個錯誤不必理會,如何屏蔽它,不進行捕捉它
解答:對全局使用,可以在db2安裝目錄下的cfg/db2cli.ini文件里添加如下:
IgnoreWarnList = "'sqlstate1', 'sqlstate2', ..." ,或使用命令db2 update cli cfg for section 段名 using "'sqlstate1', 'sqlstate2', ...";對某個應用,如在存儲過程中,使用DECLARE CONTINUE HANDLER FOR SQLSTATE ‘01504’這種方式,跳過這種錯誤。
1.30 常用的幾中數據類型的精確度和長度為多少
解答:
SMALLINT -32768~32767(精度為5的兩字節的整型)
INTEGER -2147483648~2147483647(精度為10的4字節的整型)
BIGINT -9223372036854775808~9223372036854775807(精度為19的8字節整型)
REAL -3.402E+38~-1.175E-37或1.175E-37~3.402E+38(單精度浮點數
是一個實數的32位近似值)
DOUBLE/FLOAT (雙精度浮點數是一個實數的64位近似值)
DECIMAL/NUMERIC (小數點的位置是由該DECIMAL數的精度和規模決定,規模
是該數的小數部分個數,其不能為負數和大於精度;最大精度為31)
CHAR 字符串的長度是有序字節數;長度一分配好就固定了,其長度從1~254。
VARCHAR 有三種變長字符串:
VARCHAR 32672字節長
LONG VARCHAR 32700字節長
CLOB 2G字節長(2147483647字節長)
1.31 使用EXECUTE執行SQL語句時需要注意些什么
解答:EXECUTE IMMEDIATE host-variable中的host-variable必須是小於最大語句的長度65535的字符串;如果SQL語句值需要執行一次或不頻繁,可以使用EXECUTE IMMEDIATE;如果SQL語句需要重復地執行,應該使用PREPARE和EXECUTE語句,使用EXECUTE語句可以用參數標志;注意EXECUTE語句不能和SELECT和VALUES語句一起使用。PREPARE跟游標一起使用,就不需要EXECUTE語句。
1.32 通常如何使用GET DIAGNOSTICS語句
解答:使用GET DIAGNOSTICS 變量 = ROW_COUNT語句可以獲取最后一次執行INSERT、UPDATE或DELETE之后的記錄數;DB2 SQL PL 支持GET DIAGNOSTICS語句獲取SQL語句執行的信息,它可以用來返回CONDITION HANDLER的錯誤信息;GET DIAGNOSTICS EXCEPTION 1 變量 = MESSAGE_TEXT;但這樣就不能再獲取行數了。注意:GET DIAGNOSTICS語句是不支持SELECT和SELECT INTO語句的。
1.33 如何查看DB2的日志
解答:在$HOME/sqllib/db2dump目錄下,以c開頭的目錄為核心文件所在的目錄(如:c56772.010),目錄名以字母“c”開頭,后跟受影響進程的進程標識(pid)號,擴展名是數據庫分區號;沒有字符開頭的文件轉儲文件,它是在發生錯誤時創建的,它包含將有助於診斷問題(例如,內部控制塊)的其它信息;db2diag.log為診斷日志,db2inst1.nfy紀錄管理日志。
1.34 無法刪除數據庫
如果當前數據庫仍在被使用,刪除時將無法刪除,並提示:
SQL1035N The database is currently in use. SQLSTATE=57019
解答:先將所有與數據庫的連接斷連:db2 connect reset(或db2 terminate),並將數據庫離線(offline):db2 deactivate db 數據庫名,然后再刪除數據庫。或者使用stopsap或db2stop停止db2數據庫,然后db2start
1.35 查詢數據庫系統表中的對象失敗
比如我們要從系統存儲過程表中查詢我們創建的某個存儲過程的信息,如下所示:
SELECT count(*) FROM syscat.procedures where procname = sObjectName
如果sObjectName為小寫的字符串,執行該查詢語句將返回:
0 record(s) selected
解答:由於我們創建的對象,會在系統表中保存相關信息,而對象名在系統表中會變成大寫,所以我們要從系統表中指定查詢我們創建的對象時一定要使用大寫,可以使用upper()來改為大寫。
1.36 在DB2數據庫中如何將整型轉換為字符型
解答:在oracle中有一個to_char()的函數可以將整型轉換為字符型,在DB2中也存在相似的函數char()來轉換。
1.37 在對某個對象操作時,其名稱由幾部分連接而成,這樣有時無法操作成功
解答:由於對象名由幾部分組成,這樣在連接組合時,各部分之間可能存在空白帶,導致對象名和數據庫實際的不一致,從而無法進行訪問操作。因此,需要在連接之前,使用ltrim和rtrim將各部分的左右空白帶去掉。
1.38 在多處使用同一個游標時,第一次使用后,第二次使用就發生錯誤,這是怎么回事呢?
解答:可能是前面使用完游標后,沒有將游標關閉,下次接着再使用該游標時,發現該游標已打開,在使用中,將發生錯誤。應在每次使用完游標后,將其關閉。
1.39 在SuSe9下執行raw命令將裸設備和邏輯卷掛接時裸設備的歸屬屬性會發生改變。
執行含有raw命令的腳本時,原歸屬於db2inst1.db2grp1的裸設備,變為歸屬屬性為root.disk,在raw命令后加上修改歸屬命令chown無法執行。
解答:執行raw命令后歸屬屬性會變為root.disk,但在剛執行raw命令后無法接着執行chown命令,因此,我們在raw命令后加上sleep 2語句,再執行chown命令即可。