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] 值才能知道真正原因。