14.系統記錄架構
14-1SQLCA系統記錄架構
SQLCA(SQL
Communication Access) 係由系統提供之系統記錄架構,作為 back end
與 front end 之間溝通之用,當發生 I/O 狀態時,系統會記錄該狀態於SQLCA 中
,front end 即可依據其其內容得知 I/O 運作是否成功,再決定往後執行的步驟。
SQLCA
為系統定義之 GLOBAL 變數,以下為其架構並介紹其內容與用途:
DEFINE SQLCA
RECORD
SQLCODE
INTEGER,
SQLERRM
CHAR(71),
SQLERRP
CHAR(8),
SQLERRD
ARRAY[6] OF INTEGER,
SQLAWARN CHAR(8)
END RECORD
.SQLCODE :表示
I/O 的結果
0 表示 I/O 成功
100 表示 NOTFOUND
< 0 表示 I/O 失敗
.SQLERRM :保留未用
.SQLERRP :保留未用
.SQLERRD :為一個含有6個
INTEGER 之陣列
SQLERRD[1]:保留未用
SQLERRD[2]:新增時 SERIAL 欄位所傳回之值
SQLERRD[3]:處理資料的筆數
SQLERRD[4]:查詢時預估的 CPU COST
SQLERRD[5]:SQL指令之錯誤位移
SQLERRD[6]:最後一個 ROWID 值
.SQLAWARN :為一個含有8個字元的字串,以記錄I/O時產生的警告訊息。若
正確無誤,則相對應之字元設定為空白,否則會被設定為"W"。
SQLAWARN[1]:若第2至第8字元中任意一個被設成"W",則此字元亦為
"W",否則為空白。
SQLAWARN[2]:若資料太長而被截掉時,會被設成
"W"。
SQLAWARN[3]:若 aggregate
function(如 SUM,AVG,MAX,MIN) 處理時
遇到 NULL 值,則會被設成"W"。
SQLAWARN[4]:若查詢時,若欲查詢的欄位數目和
INTO 之變數數目不合
時,會被設成 "W"。
SQLAWARN[5]:如轉換 float 成
integer 時,則會被設成 "W"。
SQLAWARN[6]:保留未用
SQLAWARN[7]:保留未用
SQLAWARN[8]:保留未用
14-2 SQLCA.SQLCODE 是否等於 STATUS ?
因
sqlca.sqlcode 係用以溝通 front end 和 back end ,因此只有 I/O 發生時才會更
改 sqlca ,同時 status 也被設定等於 sqlca.sqlcode 值。但若只是純粹 front end 的
動作(如 display),則只有 status 會被設定,而sqlca.sqlcode 則保持不變。為了避
免錯誤,要注意下列兩件事:
ヾ.若要以 status 判斷 I/O 是否成功,在 I/O 後立即判斷 status,中間不可插入
任何會更改 status 之指令。
ゝ.若要以
sqlca.sqlcode 判斷 I/O 是否成功,在 I/O 後除非有新的 I/O 發生,不
然允許先執行其它 frint end 之指令,以後再予以判斷。
CREATE DATABASE
dbtest
CREATE TABLE tab (
col1
serial(1000),
col2
char(3),
col3
smallint)
假設 TABLE tab
已有3筆資料:
col1 col2 col3 (rowid)隱含欄位
1000 AAA (null)
1
1001 BBB 1000 2
1002 CCC 2000 3
DATABASE dbtest
MAIN
DEFINE io_tab RECORD
col1 like tab.col1,
col2 like tab.col2,
col3 like tab.col3,
col4 integer
END RECORD
DEFINE total_col3 integer
DEFINE work_col2 char(2)
WHENEVER ERROR CONTINUE
§例:
SELECT *
FROM tab
WHERE col2 =
"BBB"
DISPLAY sqlca.sqlcode,sqlca.sqlerrd[6]
結果: 0
3
§例:
SELECT *
FROM tab
WHERE col2 =
"DDD"
DISPLAY sqlca.sqlcode
結果: 100
§例:
SELECT SUM(col3)
INTO total_col3
FROM tab
DISPLAY total_col3,sqlca.sqlawarn
結果: 300 W W
因內含一個 null 值,所以第1,3位設定為 W
§例:
SELECT *
INTO io_tab.*
FROM tab
WHERE col2 =
"BBB"
DISPLAY sqlca.sqlcode,sqlca.sqlerrd[3],sqlca.sqlawarn
結果: 0
1 W W
select variable_list 數目只有3個,但 io_tab 有4個,所以第1,4位設定為 W
§例:
SELECT col2
INTO work_col2
FROM tab
WHERE col2 =
"AAA"
DISPLAY sqlca.sqlcode,sqlca.sqlerrd[3],sqlca.sqlawarn
結果: 0
1 WW
因第3個字元被截掉,所以第1,2位設定為 W
§例:
UPDATE tab
SET col3
= 1000
DISPLAY sqlca.sqlerrd[3]
結果: 3
因總共更正3筆資料
§例:
INSERT INTO tab
VALUES(0,"DDD",3000)
DISPLAY sqlca.errd[2]
結果: 103
因總共更正3筆資料
§例:
SELECT *
FROM tab
WHERE col1 = 999
DISPLAY status,sqlca.sqlcode
結果: 100 100
§例:
SELECT *
FROM tab
WHERE col1 = 999
DISPLAY "STATUS will
be update !!"
DISPLAY status,sqlca.sqlcode
結果:STATUS will be update !!
0 100
此時 status 不再等於 sqlcode
14-2 如何判斷 I/O 是否成功
_
┌──────┬───────┬────────┬────────┬─────┐
│ │ INSERT │ UPDATE │ DELETE │
SELECT │
├──────┼───────┼────────┼────────┼─────┤
│ │ 成功 失敗 │ 成功 失敗 │ 成功 失敗 │ 成功 失敗│
├──────┼───────┼────────┼────────┼─────┤
│SQLCODE │ 0 <0 │
0 0,<0
│ 0 <0 │ 0
100│
├──────┼───────┼────────┼────────┼─────┤
│SQLERRD[3] │ 1 0 │ ≧1 0 │ ≧1 0 │
1 0 │
└──────┴───────┴────────┴────────┴─────┘
在 update 和 delete 時,若符合條件之資料可能不只一筆,因此執行後sqlerrd[3]
值會 ≧1;但失敗時則有兩種情行發生:
ヾ. sqlcode = 0,表示沒有符合資料可供 update/delete,故 sqlcode= 0
ゝ. sqlcode <
0,表示
update/delete 失敗,可能資料被 LOCK 住等,必須檢查
SQLERRD[2] 值才能知道真正原因。