<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 33.8\. 錯誤處理 本節描述了如何處理異常情況以及嵌入SQL程序的警告。有兩個非排他性功能可以解決。 * 配置回調用來處理警告以及使用`WHENEVER`命令處理錯誤條件。 * 關于錯誤或者警告的詳細信息可以從`sqlca`變量中獲得。 ## 33.8.1\. 設置回調 當產生特定條件時,捕獲錯誤和警告的一個簡單方法是設置一個要執行的具體操作。通常: ``` EXEC SQL WHENEVER _condition_ _action_; ``` `_condition_`可以是下列之一: `SQLERROR` 當在SQL語句執行期間發生錯誤時,調用指定操作。 `SQLWARNING` 當在SQL語句執行期間發生警告時,調用指定操作。 `NOT FOUND` 當SQL語句檢索或者影響零行,則調用指定操作。(這個條件不是錯誤, 但是你可能對特意處理它感興趣。) `_action_`可以是下列之一: `CONTINUE` 這實際上意味著該條件被忽略。這是缺省的。 `GOTO` `_label_``GO TO` `_label_` 跳轉到指定標簽(使用C `goto`語句)。 `SQLPRINT` 輸出標準錯誤信息。這對于簡單程度或者原型期間非常有用。 不能配置該信息的詳細信息。 `STOP` 調用`exit(1)`,這將終止程序。 `DO BREAK` 執行C語句`break`。這只有在循環中或者`switch` 語句中使用。 `CALL` `_name_` (`_args_`) `DO` `_name_` (`_args_`) 調用具有指定參數的指定C函數。 SQL標準僅僅提供`CONTINUE`和`GOTO` (和`GO TO`)操作。 下面是一個你可能想在簡單程序中使用的例子。當發生警告以及發生錯誤終止程序時, 它輸出一個簡單消息: ``` EXEC SQL WHENEVER SQLWARNING SQLPRINT; EXEC SQL WHENEVER SQLERROR STOP; ``` 語句`EXEC SQL WHENEVER`是SQL預處理器的指令。 而不是C語句。 錯誤或者警告操作設置處理器出現的地方中適用的所有嵌入SQL語句。 除非在第一個`EXEC SQL WHENEVER`和產生條件的SQL語句之間 為同一條件設置不同的操作,不管C程序中的控制流。 所以下面兩個C程序片段都不會產生期望效果: ``` /* * WRONG */ int main(int argc, char *argv[]) { ... if (verbose) { EXEC SQL WHENEVER SQLWARNING SQLPRINT; } ... EXEC SQL SELECT ...; ... } ``` ``` /* * WRONG */ int main(int argc, char *argv[]) { ... set_error_handler(); ... EXEC SQL SELECT ...; ... } static void set_error_handler(void) { EXEC SQL WHENEVER SQLERROR STOP; } ``` ## 33.8.2\. sqlca 為了更強大的錯誤處理, 嵌入SQL接口提供了使用下列結構的名字`sqlca`(SQL通信區) 的全局變量。 ``` struct { char sqlcaid[8]; long sqlabc; long sqlcode; struct { int sqlerrml; char sqlerrmc[SQLERRMC_LEN]; } sqlerrm; char sqlerrp[8]; long sqlerrd[6]; char sqlwarn[8]; char sqlstate[5]; } sqlca; ``` (在一個多線程程序中,每一個線程自動獲取`sqlca` 的拷貝。該工作類似于標準C全局變量`errno`的處理。) `sqlca`涵蓋警告和錯誤。如果在語句執行期間發生 多個警告和錯誤,那么`sqlca`將只包含最后一個信息。 如果在最后SQL語句沒有發生錯誤,則`sqlca.sqlcode`為0, `sqlca.sqlstate`是 `"00000"`。如果發生了警告或者錯誤,那么 `sqlca.sqlcode`是負數并且 `sqlca.sqlstate`不同于 `"00000"`。正數`sqlca.sqlcode` 表示無害條件,比如最后查詢返回零行。 `sqlcode`和`sqlstate`是兩個 不同的錯誤編碼方案;詳情如下。 如果最后一個SQL語句成功了,那么`sqlca.sqlerrd[1]` 包含處理行的OID,如果適用,則`sqlca.sqlerrd[2]` 包含處理或返回行的行數,如果適用該命令。 在錯誤或警告的情況下,`sqlca.sqlerrm.sqlerrmc` 將包含描述錯誤的字符串。字段`sqlca.sqlerrm.sqlerrml` 包含存儲在`sqlca.sqlerrm.sqlerrmc` (`strlen()`的結果,C程序員不感興趣)中的錯誤信息。 注意一些消息太長而不適合固定大小的`sqlerrmc`數組; 它們將被截斷。 在一個警告的情況下,`sqlca.sqlwarn[2]`設置為 `W`。(在所有其他情況下,它被設置為不同于`W` 的東西。)如果`sqlca.sqlwarn[1]`被設置為 `W`,那么一個值被存儲在宿主變量的時候,截斷它。 如果任何其他元素設置為顯示一個警告,則`sqlca.sqlwarn[0]` 設置為`W`。 字段`sqlcaid`, `sqlcabc`, `sqlerrp`,以及 `sqlerrd`和 `sqlwarn`的剩余元素 目前沒有任何有用信息。 在SQL標準中沒有定義結構`sqlca`, 但是在其他幾個SQL數據庫系統中實現了。定義核心是相似的,但是如果你想要 編寫可移植應用程序,那么你應該仔細調查不同的實現。 這是一個結合`WHENEVER`和`sqlca`的使用的例子, 當發生錯誤時,輸出`sqlca`的內容。 在安裝更多"user-friendly"錯誤處理程序之前, 這可能用于調試或者原型應用。 ``` EXEC SQL WHENEVER SQLERROR CALL print_sqlca(); void print_sqlca() { fprintf(stderr, "==== sqlca ====\n"); fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode); fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml); fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc); fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n", sqlca.sqlerrd[0],sqlca.sqlerrd[1],sqlca.sqlerrd[2], sqlca.sqlerrd[3],sqlca.sqlerrd[4],sqlca.sqlerrd[5]); fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0], sqlca.sqlwarn[1], sqlca.sqlwarn[2], sqlca.sqlwarn[3], sqlca.sqlwarn[4], sqlca.sqlwarn[5], sqlca.sqlwarn[6], sqlca.sqlwarn[7]); fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate); fprintf(stderr, "===============\n"); } ``` 結果可能如下所示(這里錯誤歸因于表名字拼寫錯誤): ``` ==== sqlca ==== sqlcode: -400 sqlerrm.sqlerrml: 49 sqlerrm.sqlerrmc: relation "pg_databasep" does not exist on line 38 sqlerrd: 0 0 0 0 0 0 sqlwarn: 0 0 0 0 0 0 0 0 sqlstate: 42P01 =============== ``` ## 33.8.3\. `SQLSTATE` vs. `SQLCODE` 字段`sqlca.sqlstate`和 `sqlca.sqlcode`是提供錯誤碼的兩個不同模式。 兩者來自SQL標準,但是`SQLCODE`在標準SQL-92 版本中已經過時,并且在后期版本中已經廢除。因此, 強烈建議新應用使用`SQLSTATE`。 `SQLSTATE`是五字符數組。 五字符包含數字或者表示不同錯誤和警告條件代碼的大寫字母。 `SQLSTATE`有一個分層模式: 前兩個字符表示條件的一般類,最后三個字符表示一般條件的子類。 通過代碼`00000`表示成功狀態。 `SQLSTATE`代碼是SQL標準中定義最多部分。 PostgreSQL服務器本地支持 `SQLSTATE`錯誤代碼;因此通過在所有應用程序中 使用該錯誤代碼方案實現高度一致性。 更多信息參閱[Appendix A](#calibre_link-120)。 `SQLCODE`,已廢棄的錯誤編碼方案,是一個簡單的integer。 0值表示成功,正值表示額外信息成功,負值表示錯誤。 SQL標準僅僅定義正值+100,這表示返回最后命令或者影響零行,并且 沒有明確負值。因此,該方案實現差的移植性,而且沒有分層編碼安排。 從歷史角度,PostgreSQL嵌入的SQL預處理器 為它的使用分配了一些指定`SQLCODE`。 使用數值和符號名稱將它列在下面。記住這些是不能移植到其他SQL實現的。 為了簡化應用程序移植到`SQLSTATE`方案,相應的 `SQLSTATE`也被列出來。然而, 在兩個方案(實際上是多對多)之間沒有一對一或者一對多映射, 因此在每種情況下你應該咨詢列在[Appendix A](#calibre_link-120)中的全球`SQLSTATE`。 這些是已分配的`SQLCODE`值: 0 (`ECPG_NO_ERROR`) 表明沒有錯誤。(SQLSTATE 00000) 100 (`ECPG_NOT_FOUND`) 這是無害條件表明檢索最后一條命令或者處理零行,或者你在游標結尾。(SQLSTATE 02000) 當在循環中處理游標時,你可以使用該代碼作為檢測什么時候終止循環的方式,像這樣: ``` while (1) { EXEC SQL FETCH ... ; if (sqlca.sqlcode == ECPG_NOT_FOUND) break; } ``` 但是`WHENEVER NOT FOUND DO BREAK`有效的內部執行這個,因此 在明確寫這個時通常沒有優勢。 -12 (`ECPG_OUT_OF_MEMORY`) 表明耗盡了你的虛擬內存。作為`-ENOMEM`定義該數值。 (SQLSTATE YE001) -200 (`ECPG_UNSUPPORTED`) 表明預處理器產生了該庫不知道的一些東西。可能你正在該預處理器和該庫不兼容版本上運行。(SQLSTATE YE002) -201 (`ECPG_TOO_MANY_ARGUMENTS`) 這意味著指定命令比期望命令宿主變量更多。(SQLSTATE 07001或者07002) -202 (`ECPG_TOO_FEW_ARGUMENTS`) 這意味著指定命令比期望命令宿主變量更少。(SQLSTATE 07001或者07002) -203 (`ECPG_TOO_MANY_MATCHES`) 這意味著查詢返還多行但是語句只準備存儲一個結果行(比如, 因為指定變量不是數組)。(SQLSTATE 21000) -204 (`ECPG_INT_FORMAT`) 宿主變量是類型`int`,并且數據庫中數據是不同類型,而且 包含不能解釋為`int`類型的值。 為這種轉換該庫使用`strtol()`。(SQLSTATE 42804) -205 (`ECPG_UINT_FORMAT`) 宿主變量是類型`無符號int`,并且數據庫中數據是不同類型,而且 包含不能解釋為`無符號int`類型的值。 為這種轉換該庫使用`strtoul()`。(SQLSTATE 42804) -206 (`ECPG_FLOAT_FORMAT`) 宿主變量是類型`float`,并且數據庫中數據是另一種類型,而且 包含不能解釋為`float`類型的值。 為這種轉換該庫使用`strtod()`。(SQLSTATE 42804) -207 (`ECPG_NUMERIC_FORMAT`) 宿主變量是類型`numeric`,并且數據庫中數據是另一種類型,而且 包含不能解釋為`numeric`類型的值。(SQLSTATE 42804) -208 (`ECPG_INTERVAL_FORMAT`) 宿主變量是類型`interval`,并且數據庫中數據是另一種類型,而且 包含不能解釋為`interval`類型的值。(SQLSTATE 42804) -209 (`ECPG_DATE_FORMAT`) 宿主變量是類型`date`,并且數據庫中數據是另一種類型,而且 包含不能解釋為`date`類型的值。(SQLSTATE 42804) -210 (`ECPG_TIMESTAMP_FORMAT`) 宿主變量是類型`timestamp`,并且數據庫中數據是另一種類型,而且 包含不能解釋為`timestamp`類型的值。(SQLSTATE 42804) -211 (`ECPG_CONVERT_BOOL`) 這意味著宿主變量是類型`bool`, 并且數據庫中數據既不是`'t'`也不是 `'f'`。(SQLSTATE 42804) -212 (`ECPG_EMPTY`) 發送到PostgreSQL服務器的語句是空的。 (這通常不會發生在嵌入SQL程序中,因此它可能指向一個內部錯誤。) (SQLSTATE YE002) -213 (`ECPG_MISSING_INDICATOR`) 返回一個空值,而且沒有提供空指示符變量。(SQLSTATE 22002) -214 (`ECPG_NO_ARRAY`) 一個普通變量被用于需要數組的地方。(SQLSTATE 42804) -215 (`ECPG_DATA_NOT_ARRAY`) 數據庫返回需要數組值位置的普通變量。(SQLSTATE 42804) -220 (`ECPG_NO_CONN`) 該程序試圖訪問一個不存在的連接。(SQLSTATE 08003) -221 (`ECPG_NOT_CONN`) 該程序試圖訪問一個存在但無法打開的連接。(這是一個內部錯誤。)(SQLSTATE YE002) -230 (`ECPG_INVALID_STMT`) 你正嘗試使用的語句未準備好。(SQLSTATE 26000) -239 (`ECPG_INFORMIX_DUPLICATE_KEY`) 重復鍵錯誤,違反唯一約束(Informix兼容模式)。(SQLSTATE 23505) -240 (`ECPG_UNKNOWN_DESCRIPTOR`) 未找到指定描述符。你嘗試使用的語句未準備好。(SQLSTATE 33000) -241 (`ECPG_INVALID_DESCRIPTOR_INDEX`) 指定的描述符索引超出了范圍。(SQLSTATE 07009) -242 (`ECPG_UNKNOWN_DESCRIPTOR_ITEM`) 請求無效描述符項。(這是個內部錯誤。) (SQLSTATE YE002) -243 (`ECPG_VAR_NOT_NUMERIC`) 在動態語句執行的過程中,數據庫返回一個數值,但宿主變量不是數字的。 (SQLSTATE 07006) -244 (`ECPG_VAR_NOT_CHAR`) 在動態語句執行的過程中,數據庫返回一個非數值, 但宿主變量是數字的。 (SQLSTATE 07006) -284 (`ECPG_INFORMIX_SUBSELECT_NOT_ONE`) 子查詢結果不是單行(Informix兼容模式)。(SQLSTATE 21000) -400 (`ECPG_PGSQL`) PostgreSQL服務器產生一些錯誤。 包含的錯誤消息來自PostgreSQL服務器。 -401 (`ECPG_TRANS`) PostgreSQL發出信號我們不能啟動,提交,或者回滾事務。 (SQLSTATE 08007) -402 (`ECPG_CONNECT`) 嘗試與數據庫的連接沒有成功。(SQLSTATE 08001) -403 (`ECPG_DUPLICATE_KEY`) 重復鍵錯誤,違反唯一約束。(SQLSTATE 23505) -404 (`ECPG_SUBSELECT_NOT_ONE`) 子查詢結果不是單行。(SQLSTATE 21000) -602 (`ECPG_WARNING_UNKNOWN_PORTAL`) 指定一個無效游標名。(SQLSTATE 34000) -603 (`ECPG_WARNING_IN_TRANSACTION`) 事務正在進行中。(SQLSTATE 25001) -604 (`ECPG_WARNING_NO_TRANSACTION`) 這是一個非活躍(進行中)事務。(SQLSTATE 25P01) -605 (`ECPG_WARNING_PORTAL_EXISTS`) 指定一個已經存在游標名。(SQLSTATE 42P03)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看