嵌套SQL語句訪問DB2中SQLCA的調用技巧

來源:互聯網
上載者:User

標籤:mil   ntp   sqlstate   函數定義   可靠   儲存   電話   意義   使用者id   

在IBM的關係型資料庫產品DB2中,使用SQL Communication Area(SQLCA)將程式中嵌套的SQL語句執行情況返回給程式。

在程式中有針對性地對SQLCA實施調用,可對程式中各類SQL語句的執行結果實施控制,從而避免程式的意外終止。同一時候,也能夠提高執行效率,減小系統開銷和處理時間。本文將對此作一簡要介紹。
SQLCA的結構
SQLCA的結構定義例如以下:
struc sqlca
{        unsigned char     sqlcaid[8];
long              sqlabc;
long              sqlcode;
short             sqlerrml;
unsigned char     sqlerrnmc[10];
unsigned char     sqlerrp[8];
long              sqlerrd[6];
unsigned char     sqlwarn[21];
unsigned char     sqlstate[5];        }
結構中各個域各有不同的含義和用途。部分域的功能和用途將在下面各小節中做具體探討,其他一些域的含義例如以下:
sqlcaid:        標識性域。包括字串“sqlca”.
Sqlabc:        包括sqlca結構的長度。
Sqlerrml:        包括sqlerrmc域中資料的實際長度。
Sqlerrmc:         由0或多個字串組成,它對返回的值給以一個更具體的解釋。如返回的代碼錶示表沒找到,則此域中包括未找到的表名。
Sqlerrp:         包括一些對使用者沒用的論斷資訊。
Sqlstate:         長度為5的字串,它指示SQL語句的查詢結果。

與sqlca不同的是,它遵循ANSI/ISOSQL92的標準,所以,雖然不同資料庫產品的sqlca結構中sqlcode域的含義不同。但sqlstate域的含義是同樣的。


調用方法
DB2通過一個函數:sqlaintp。能夠方便地讀取sqlca中SQL語句運行後的結果和錯誤。此函數定義在sql.h中,可通過下述語句實現對其定義:
EXEC SQL INCLUDE sqlca.h 
Sqlaintp函數格式例如以下:
int sqlaintp
(        char  *buffer
short   buffer_size
short   line_width
struct  sqlca *sqlca        )
當中, buffer為存放了sqlca資訊的緩衝區;buffer_size中存放了buffer的長度;line_width存放了兩個運行符之間的字元長度。

函數傳回值為正時代表sqlca資訊的長度,為負時代表沒有sqlca資訊返回。一般來講,sqlca資訊都可存放在長度為512個位元組的緩衝區中。
為了處理各種錯誤情況,DB2提供了WHENEVER語句。其詳細用法例如以下:
(1)        EXEC SQL WHENEVER SQLERROR action       SQLCODE<0時,運行action.
(2) EXEC SQL WHENEVER SQLWARNING action     SQLCODE>;0但不為100且SQLWARN[0]=W時時,運行action.
(3) EXEC SQL WHENEVER NOT FOUND action      SQLCODE=100時,運行action.
當中action有兩種可能:
CONTINUE:繼續運行程式中的還有一條命令。
GO TO label:轉到label指定的語句開始。
值得注意的是,WHENEVER語句的作用範圍到下一個WHENEVER時終止。


對SQLCODE的調用
   在對SQLCA的調用中,最常見的就是通過訪問SQLCODE來實現的。

非常多程式猿甚至在每條SQL語句運行完成後都設定檢查SQLCODE傳回值的代碼,以對程式的運行進行監控。當傳回值為+0的時。表明SQL語句運行成功。傳回值為+100時,表明滿足檢索條件的記錄沒找到。

一般來說。負的SQLCODE返回負值意味著SQL語句運行失敗,程式猿可在程式中實現依據不同的SQLCODE傳回值,採取不同的程式流程以實現錯誤控制。比如。當SQLCODE的傳回值為-911時, 表明系統檢測到了死結(Dead Lock),程式猿可針對這樣的情況採取下面兩種處置方法:
(1)設定迴圈,重複執行查詢請求並檢測SQLCODE,直至傳回值為+0(運行成功)。
(2)設定一個計數器,執行查詢請求到一定次數後終止程式或向使用者發出警報。


值得注意的是,為了保證資料的完整性。有時須要針對返回的錯誤類型對資料庫進行復原(ROLLBACK)操作,且復原的起點不一定是未運行成功的SQL語句導致系統所處於的狀態。復原的起點與SQL語句的巢狀型別(動態,靜態。複合式)以及錯誤類型都有關係。

尤其是後者,由於有些錯誤類型會導致系統作一個隱式的復原(比如SQLCODE -911),從而使復原的起點推斷更為複雜。
   雖然多數情況下我們希望SQL語句運行成功,但有些時候。通過一個有益“製造”的負的SQLCODE傳回值,能夠使程式中的邏輯推斷更為簡潔。還可在較大程度上降低系統開銷。我們能夠設想這樣一種情況:郵電局有兩種話費收據,一種是針對僅僅安有一部電話的使用者的,還有一種是針對安有多部電話的使用者的,兩種話費收據上的項目個不同樣,須要不同的子程式進行處理。在話費收據處理常式中,首先依據每個使用者唯一的ID號檢索相應的電話號碼。並設定計數器對檢索到的記錄數(安裝電話數)進行統計,當某使用者ID僅相應一條電話號碼記錄時。調用單機使用者話費收據處理常式對相應使用者的話費資料進行處理;當某使用者ID僅相應多條電話號碼記錄時,調用多機使用者話費收據處理常式對相應使用者的話費資料進行處理。不管何種情況。都需對使用者的資料又一次進行讀取方可進行下一步處理。也就是說,須要對一個使用者的電話資料進行兩次讀取才幹完畢相應的資料處理。這無疑會極大的添加系統處理時間。

通過對SQLCODE的調用。能夠使這樣的情況得以顯著改善。首先。針對每個使用者的ID作一個SELECT操作,然後檢查SQLCODE傳回值,當傳回值為+0時,表明該使用者僅僅安裝了一部電話;當傳回值為-811時。表明該使用者安裝了不止一部電話。可由此推斷應由那種程式來處理使用者話費資訊。採用這樣的解決方式,僅僅對使用者的資料讀取一次就可完畢使用者的話費處理。差點兒降低了一半的系統處理時間。

與其他諸如改變表的結構等方法。此種方法對系統的修改最小。而且簡便易行。效果明顯。


   在對資料庫訪問的程式中,程式通常要求實現例如以下功能:更新資料庫中的某一條記錄,當這條記錄不存在時建立對應的記錄。

比較常見的做法是,先進行一次SELECT查詢,當SQLCODE返回+0時,表明此條記錄已存在,然後再重讀此記錄對其進行UPDATE操作;當SQLCODE返回+100時,表明對應記錄不存在,接下來再進行INSTER操作。還有一種實現方岸依據資料訪問的特點,當對資料的更新多於新值插入時。直接進行UPDATE操作。當SQLCODE返回+0時更新成功,反之。返回+100時,需對其進行INSERT操作。當新值插入要多餘於更新操作時。首先進行INSERT操作。SQLCODE值為+0時插入成功,否則返回-803,表明原記錄已存在,須要進行UPDATE操作。顯而易見,多數情況下,另外一種方法僅僅需對資料進行一次操作就可以,從而提高系統的處理效率。
對SQLWARN的調用
   雖然程式猿通常總是忽略SQL的警告錯誤。但適當的使用能夠協助程式檢測到各種潛在的錯誤,而且能夠使編程更加簡潔。

因此,此類警告資訊亦應受到程式猿的重視。
   警告資訊在SQLCA中有兩種表示方法。

每個除了+100以外的SQLCODE正傳回值都代表一定的警告資訊;同一時候,SQLCA中的SQLWARN[n](n=1,2,3,4。5。6或A)傳回值也代表著對應的警告資訊。當系統發現警告錯誤時,系統會以這兩種方式通知程式。

此時。查詢可能會返回一些結果。但此時的結果極有可能是錯誤或不完整的。當SQLWARN[O]=W時。DB2提供了協助使用者推斷詳細警告類型的資訊,其對應值及含義例如以下表:


SQLCA值        傳回值        警告內容
SQLWARN[1]        W        序主變數長度不夠而發生截取
SQLWARN[2]        W        欄位功能處理的資料中有空(NULL)值
SQLWARN[3]        W        返回欄位個數大於程式定義的序主變數個數
SQLWARN[4]        W        在UPDATE或DELETE操作中未指定WHERE條件
SQLWARN[6]        W        對時間資料進行數學運算後進行修正
SQLWARN[A]        W        轉換出錯
       如果某學校要計算某一學期各班。各科。個人的平均成績。

當中。個人平均成績=(個人總分)/(本學期所學科目數)。

因為工作人員疏忽,誤將某一同學的學期學習科目輸為0。

在使用嵌套SQL語句的程式對相關資料進行處理時,SQLCODE傳回值為-802(除數為零)導致程式終止執行。雖然使用者知道可能是某一項資料錯誤,但無法知道詳細是哪一項資料錯誤。對於一個擁有較多資料的學校來說,尋找起來是非常費事的。

通過下述辦法能夠非常好的解決這一問題:在定義代表計算結果的序主變數的同一時候,為其指定一個能夠為空白的指示變數,如 :AVGRD :IND代表序主變數為AVGRD,指示變數為IND。此時發生被零除錯誤時,指示變數值被設為-2,同一時候SQLCODE傳回值為+802警告資訊。

程式捕捉到此資訊時,可向使用者提供對應的資訊,協助使用者確定出錯資料位元置。
   當SQLWARN[O]的值為W時,表明系統檢測到警告錯誤。此時系統提供的警告資訊也可被程式猿所利用。比方:當程式把一個表中的某一字元型欄位值傳入一個比其長度要短的序主變數中時,發生字元截取。雖然此時SQLCODE會返回+0,但程式擷取的資料是不完整的。通過為序主變數指定一個指示變數。發生相同錯誤時,SQLWARN[O]和SQLWARN[1]的傳回值都為W。同一時候,指示變數被賦給了欄位中資料的實際長度。此種方法甚至能夠用來推斷表中欄位中字串資料的實際長度。
對SQLERRD數組的調用
    SQLERRD是SQLCA中代表SQL查詢執行結果的一個數組。數組中的不同元素有不同的含義。

當中較經常使用的是SQLERRD[3]。它將返回程式中上一次INSERT,UPDATE或DELETE操作所影響到的記錄數。否則。程式須要藉助一定的迴圈來統計被以上操作影響到的記錄數。但值得注意的是。在執行DELETE操作時。假設相關欄位的刪除類型被設為CASCADE而導致被刪除其他記錄數不會被包括在內;同一時候,假設在DELETE語句中未指定WHERE條件,則SQLERRD[3]的傳回值為-1。以上兩點在使用此數組時應予以注意。SQLERRD中各元素的含義以及其對於複合式SQL語句。串連方法的不同含義例如以下:
SQLERRD元素        表示意義        複合式SQL語句        串連方式
SQLERRD[2]        儲存當前SQL語句處理的行數。但若當前SQL失敗, 則無定義; 若在數組操作中出錯, 則停於出錯行, 這時給出成功處理的行數; OPEN運行後, 清為0, FECTH 後增值(原有值+上本次fetch的行數); EXECUTE、INSERT、UPDATE、SELETE和SELECT後, 為成功處理的行數。
SQLERRD[3]        返回的記錄數(預計)及INSERT/UPDATE或DELETE操作所影響到的記錄數(不包括因限制條件而影響到的記錄)           總語句數        0:由底層客戶機的一段式提交託付確認1:一段式提交2:一段式僅僅讀提交3:兩段式提交
SQLERRD[4]        指出語句中出錯的位移, 首字元位移為0。


SQLERRD[5]        INSERT/UPDATE或DELETE操作所影響到的記錄數(包括因限制條件而影響到的記錄)        因限制條件而影響到的記錄數        無

經常使用:SQLERRD[2]  ,如:#defineSQLROWS sqlca.sqlerrd[2]


    DB2支援多種進階語言(包含當前極為流行的C和C++等)通過嵌套SQL語句對其上的資料進行訪問。同一時候,因為對多種嵌套(動態,靜態,複合式)方式的支援,更加增強了訪問的靈活性。

通過在程式中調用SQLCA。可對程式中嵌套的SQL語句的執行結果進行控制。增強了程式的可靠性。防止程式意外終止。也可使程式的編寫更加簡潔。提高程式的執行效率,縮短系統的處理時間。

嵌套SQL語句訪問DB2中SQLCA的調用技巧

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.