共用方式為


SQLGetDiagField 函式

一致性
引進版本:ODBC 3.0 標準合規性:ISO 92

摘要
SQLGetDiagField 會傳回診斷資料結構記錄的目前值(與指定的控制碼相關聯),其中包含錯誤、警告和狀態資訊。

語法


SQLRETURN SQLGetDiagField(  
     SQLSMALLINT     HandleType,  
     SQLHANDLE       Handle,  
     SQLSMALLINT     RecNumber,  
     SQLSMALLINT     DiagIdentifier,  
     SQLPOINTER      DiagInfoPtr,  
     SQLSMALLINT     BufferLength,  
     SQLSMALLINT *   StringLengthPtr);  

引數

HandleType
[輸入]控制碼類型識別碼,描述需要診斷的控制碼類型。 必須是下列其中一項:

  • SQL_HANDLE_DBC

  • SQL_HANDLE_DBC_INFO_TOKEN

  • SQL_HANDLE_DESC

  • SQL_HANDLE_ENV

  • SQL_HANDLE_STMT

SQL_HANDLE_DBC_INFO_TOKEN控制碼只能由驅動程式管理員和驅動程式使用。 應用程式不應該使用此控制碼類型。 如需SQL_HANDLE_DBC_INFO_TOKEN的詳細資訊,請參閱 在 ODBC 驅動程式 中開發連線集區感知。

Handle
[輸入]HandleType 指示之類型的診斷資料結構的控制碼。 如果 HandleType 是SQL_HANDLE_ENV, Handle 可以是共用或未共用的環境控制碼。

RecNumber
[輸入]指出應用程式從中搜尋資訊的狀態記錄。 狀態記錄號碼為 1。 如果 DiagIdentifier 引數指出診斷標頭的任何欄位, 則會忽略 RecNumber 。 如果沒有,它應該超過 0。

DiagIdentifier
[輸入]指出要傳回其值之診斷的欄位。 如需詳細資訊,請參閱中的< DiagIdentifier 引數>一節。

DiagInfoPtr
[輸出]要在其中傳回診斷資訊的緩衝區指標。 資料類型取決於 DiagIdentifier 的值 。 如果 DiagInfoPtr 是整數類型,應用程式應該使用 SQLULEN 的緩衝區,並在呼叫此函式之前將值初始化為 0,因為某些驅動程式可能只寫入較低 32 位或 16 位的緩衝區,並讓較高順序的位保持不變。

如果 DiagInfoPtr 為 Null, StringLengthPtr 仍會傳回可供 DiagInfoPtr 指向 的緩衝區中傳回的位元組總數(不包括字元資料的 Null 終止字元)。

BufferLength
[輸入]如果 DiagIdentifier 是 ODBC 定義的診斷,且 DiagInfoPtr 指向字元字串或二進位緩衝區,則此引數應該是 * DiagInfoPtr 的長度。 如果 DiagIdentifier 是 ODBC 定義的欄位,而 * DiagInfoPtr 是整數, 則會忽略 BufferLength 。 如果 *DiagInfoPtr 中的 值是 Unicode 字串(呼叫 SQLGetDiagFieldW 時), BufferLength 引數必須是偶 數。

如果 DiagIdentifier 是驅動程式定義的欄位,則應用程式會藉由設定 BufferLength 引數,向驅動程式管理員指出欄位的性質。 BufferLength 可以具有下列值:

  • 如果 DiagInfoPtr 是字元字串的指標, BufferLength 是字串的長度或SQL_NTS。

  • 如果 DiagInfoPtr 是二進位緩衝區的指標,則應用程式會將SQL_LEN_BINARY_ATTR( length ) 宏的結果放在 BufferLength 。 這會在 BufferLength 放置負值。

  • 如果 DiagInfoPtr 是字元字串或二進位字串以外的值指標, BufferLength 應具有值SQL_IS_POINTER。

  • 如果 *DiagInfoPtr 包含固定長度的資料類型, BufferLength 會視需要SQL_IS_INTEGER、SQL_IS_UINTEGER、SQL_IS_SMALLINT或SQL_IS_USMALLINT。

StringLengthPtr
[輸出]緩衝區的指標,用於傳回字元資料之 * DiagInfoPtr 中傳回的位元組總數(不包括 Null 終止字元所需的位元組數目)。 如果可用的位元組數目大於或等於 BufferLength ,則 * DiagInfoPtr 中的文字會截斷為 BufferLength 減去 Null 終止字元的長度。

傳回

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR、SQL_INVALID_HANDLE或SQL_NO_DATA。

診斷

SQLGetDiagField 不會自行張貼診斷記錄。 它會使用下列傳回值來報告其本身執行的結果:

  • SQL_SUCCESS:函式已成功傳回診斷資訊。

  • SQL_SUCCESS_WITH_INFO:* DiagInfoPtr 太小,無法保存要求的診斷欄位。 因此,診斷欄位中的資料已截斷。 若要判斷發生截斷,應用程式必須比較 BufferLength 與實際可用的位元組數目,這會寫入 * StringLengthPtr

  • SQL_INVALID_HANDLE:HandleType Handle 所 指示的控制碼 不是有效的控制碼。

  • SQL_ERROR:發生下列其中一項:

    • DiagIdentifier 引數不是其中一個有效值。

    • DiagIdentifier 引數SQL_DIAG_CURSOR_ROW_COUNT、SQL_DIAG_DYNAMIC_FUNCTION、SQL_DIAG_DYNAMIC_FUNCTION_CODE或SQL_DIAG_ROW_COUNT,但 Handle 不是語句控制碼。 (驅動程式管理員會傳回此診斷。)

    • 當 DiagIdentifier 指出診斷記錄中的欄位時 ,RecNumber 引數為負數或 0。 標頭欄位會忽略 RecNumber

    • 所要求的值為字元字串,BufferLength 小於零。

    • 使用非同步通知時,控制碼上的非同步作業尚未完成。

  • SQL_NO_DATA: RecNumber 大於 Handle 中所 指定控制碼的診斷記錄數目。 如果 Handle 沒有診斷記錄 ,函式也會針對任何正 RecNumber 傳回SQL_NO_DATA。

註解

應用程式通常會呼叫 SQLGetDiagField 來完成三個目標之一:

  1. 當函式呼叫傳回SQL_ERROR或SQL_SUCCESS_WITH_INFO時,取得特定錯誤或警告資訊(或 SQLBrowseConnect 函式 的SQL_NEED_DATA)。

  2. 若要使用呼叫 SQLExecute 、SQLExecDirect SQLBulkOperations SQLSetPos (從SQL_DIAG_ROW_COUNT標頭欄位),或判斷目前開啟資料指標中存在的資料列數目,或判斷目前開啟資料指標中存在的資料列數目,如果驅動程式可以提供此資訊(從SQL_DIAG_CURSOR_ROW_COUNT標頭欄位)。

  3. 若要判斷呼叫 SQLExecDirect SQLExecute 執行的函式(從SQL_DIAG_DYNAMIC_FUNCTION和SQL_DIAG_DYNAMIC_FUNCTION_CODE標頭欄位)。

每次呼叫 ODBC 函數時,任何 ODBC 函式都可以張貼零個或多個診斷記錄,因此應用程式可以在任何 ODBC 函數呼叫之後呼叫 SQLGetDiagField 。 不論何時,可儲存的診斷記錄數目都沒有任何限制。 SQLGetDiagField 只會擷取最近與 Handle 引數中指定的 診斷資料結構相關聯的診斷資訊。 如果應用程式呼叫 SQLGetDiagField SQLGetDiagRec 以外的 ODBC 函式,則會遺失先前具有相同控制碼之呼叫的任何診斷資訊。

只要 SQLGetDiagField 傳回SQL_SUCCESS, 應用程式就可以藉由遞增 RecNumber 來掃描所有診斷記錄。 狀態記錄的數目會在 [SQL_DIAG_NUMBER標頭] 欄位中指出。 對 SQLGetDiagField 呼叫對標頭和記錄欄位不具破壞性。 應用程式稍後可以再次呼叫 SQLGetDiagField ,以從記錄擷取欄位,只要診斷函式以外的函式尚未在過渡期間呼叫,這會在相同的控制碼上張貼記錄。

應用程式可以呼叫 SQLGetDiagField 隨時傳回任何診斷欄位,但 SQL_DIAG_CURSOR_ROW_COUNT 或 SQL_DIAG_ROW_COUNT除外,如果 Handle 不是語句控制碼,則會傳回SQL_ERROR。 如果未定義任何其他診斷欄位,則對 SQLGetDiagField 呼叫會傳回SQL_SUCCESS(如果沒有遇到其他診斷),而且會傳回欄位未定義的值。

如需詳細資訊,請參閱 使用 SQLGetDiagRec 和 SQLGetDiagField 實作 SQLGetDiagRec 和 SQLGetDiagField

呼叫非非同步執行 API 的 API 會產生 HY010「函式順序錯誤」。 不過,非同步作業完成之前,無法擷取錯誤記錄。

HandleType 引數

每個控制碼類型都可以有與其相關聯的診斷資訊。 HandleType 引數表示 Handle 的 控制碼 類型。

無法針對環境、連接、語句和描述項控制碼傳回某些標頭和記錄欄位。 下列「標題欄位」和「記錄欄位」區段中會指出不適用欄位的控制碼。

如果 HandleType 是SQL_HANDLE_ENV, Handle 可以是共用或未共用的環境控制碼。

任何驅動程式特定的標頭診斷欄位都不應該與環境控制碼相關聯。

為描述項控制碼定義的唯一診斷標頭欄位是SQL_DIAG_NUMBER和SQL_DIAG_RETURNCODE。

DiagIdentifier 引數

這個引數表示診斷資料結構所需的欄位識別碼。 如果 RecNumber 大於或等於 1,則欄位中的資料會描述函式所傳回的診斷資訊。 如果 RecNumber 為 0,則欄位位於診斷資料結構的標頭中,因此包含與傳回診斷資訊之函式呼叫相關的資料,而不是傳回特定資訊的資料。

驅動程式可以在診斷資料結構中定義驅動程式特定的標頭和記錄欄位。

使用 ODBC 2*.x* 驅動程式的 ODBC 3*.x* 應用程式,只能使用 SQL_DIAG_CLASS_ORIGIN、SQL_DIAG_CLASS_SUBCLASS_ORIGIN、SQL_DIAG_CONNECTION_NAME、SQL_DIAG_MESSAGE_TEXT、SQL_DIAG_NATIVE、SQL_DIAG_NUMBER、SQL_DIAG_RETURNCODE、SQL_DIAG_SERVER_NAME 或 SQL_DIAG_SQLSTATE 的 DiagIdentifier 引數呼叫 SQLGetDiagField 。 其他所有診斷欄位都會傳回 SQL_ERROR。

標頭欄位

下表所列的標頭欄位可以包含在 DiagIdentifier 引數中

DiagIdentifier 傳回類型 傳回
SQL_DIAG_CURSOR_ROW_COUNT SQLLEN 此欄位包含資料指標中的資料列計數。 其語意取決於 SQLGetInfo 資訊類型SQL_DYNAMIC_CURSOR_ATTRIBUTES2、SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2、SQL_KEYSET_CURSOR_ATTRIBUTES2和SQL_STATIC_CURSOR_ATTRIBUTES2,這表示每個資料指標類型可用的資料列計數(在SQL_CA2_CRC_EXACT和SQL_CA2_CRC_APPROXIMATE位中)。

此欄位的內容只會針對語句控制碼定義,而且只有在呼叫 SQLExecute SQLExecDirect SQLMoreResults 之後 。 在 語句控制碼上呼叫 具有 SQL_DIAG_CURSOR_ROW_COUNT 之 DiagIdentifier 的 SQLGetDiagField 將會傳回SQL_ERROR。
SQL_DIAG_DYNAMIC_FUNCTION SQLCHAR * 這是描述基礎函式執行之 SQL 語句的字串。 (如需特定值,請參閱本節稍後的。此欄位的內容只會針對語句控制碼定義,而且只有在呼叫 SQLExecute SQLExecDirect SQLMoreResults 之後。 在 語句控制碼上呼叫具有 SQL_DIAG_DYNAMIC_FUNCTION 的 DiagIdentifier 的 SQLGetDiagField 將會傳回SQL_ERROR。 呼叫 SQLExecute SQLExecDirect 之前 ,未定義此欄位的值。
SQL_DIAG_DYNAMIC_FUNCTION_CODE SQLINTEGER 這是數值程式碼,描述基礎函式所執行的 SQL 語句。 (如需特定值,請參閱本節稍後的。此欄位的內容只會針對語句控制碼定義,而且只有在呼叫 SQLExecute SQLExecDirect SQLMoreResults 之後。 在 語句控制碼上呼叫具有 SQL_DIAG_DYNAMIC_FUNCTION_CODE 的 DiagIdentifier 的 SQLGetDiagField 將會傳回SQL_ERROR。 呼叫 SQLExecute SQLExecDirect 之前 ,未定義此欄位的值。
SQL_DIAG_NUMBER SQLINTEGER 指定控制碼可用的狀態記錄數目。
SQL_DIAG_RETURNCODE SQLRETURN 傳回函式傳回的程式碼。 如需傳回碼的清單,請參閱 傳回碼 。 驅動程式不需要實作SQL_DIAG_RETURNCODE;它一律由驅動程式管理員實作。 如果控制碼 尚未呼叫任何函式,則會傳回SQL_SUCCESS SQL_DIAG_RETURNCODE。
SQL_DIAG_ROW_COUNT SQLLEN 受 SQLExecute、SQLExecute 、SQLExecDirect SQLBulkOperations 或 SQLSetPos 所執行 之插入、刪除或 更新影響的資料列數目。 這是在資料指標規格 執行之後 所定義的驅動程式。 此欄位的內容只會針對語句控制碼定義。 在 語句控制碼上呼叫 具有 SQL_DIAG_ROW_COUNT 的 DiagIdentifier 的 SQLGetDiagField 將會傳回SQL_ERROR。 此欄位中的資料也會在 SQLRowCount RowCountPtr 引數中 傳回。 此欄位中的資料會在每次非診斷函式呼叫之後重設,而 SQLRowCount 回的資料列計數會維持不變,直到語句設定回已備妥或已配置的狀態為止。

記錄欄位

下表所列的記錄欄位可以包含在 DiagIdentifier 引數中

DiagIdentifier 傳回類型 傳回
SQL_DIAG_CLASS_ORIGIN SQLCHAR * 字串,指出此記錄中定義 SQLSTATE 值的類別部分的檔。 其值為 Open Group 和 ISO 呼叫層級介面所定義之所有 SQLSTATE 的 「ISO 9075」。 對於 ODBC 特定的 SQLSTATEs(所有 SQLSTATE 類別為 「IM」),其值為 「ODBC 3.0」。
SQL_DIAG_COLUMN_NUMBER SQLINTEGER 如果SQL_DIAG_ROW_NUMBER欄位是資料列集或一組參數中的有效資料列編號,則此欄位會包含值,代表結果集中的資料行編號,或參數集合中的參數編號。 結果集資料行編號一律從 1 開始;如果此狀態記錄與書簽資料行有關,則欄位可以是零。 參數編號從 1 開始。 如果狀態記錄未與資料行編號或參數編號相關聯,則其值為 SQL_NO_COLUMN_NUMBER。 如果驅動程式無法判斷此記錄相關聯的資料行編號或參數編號,則此欄位的值SQL_COLUMN_NUMBER_UNKNOWN。

此欄位的內容只會針對語句控制碼定義。
SQL_DIAG_CONNECTION_NAME SQLCHAR * 字串,指出診斷記錄所關聯之連線的名稱。 此欄位是驅動程式定義的。 對於與環境控制碼相關聯的診斷資料結構,以及與任何連線無關的診斷資料結構,此欄位是長度為零的字串。
SQL_DIAG_MESSAGE_TEXT SQLCHAR * 錯誤或警告的資訊訊息。 此欄位的格式如下診斷訊息 中所述 。 診斷郵件內文沒有最大長度。
SQL_DIAG_NATIVE SQLINTEGER 驅動程式/資料來源特定的原生錯誤碼。 如果沒有原生錯誤碼,驅動程式會傳回 0。
SQL_DIAG_ROW_NUMBER SQLLEN 此欄位包含資料列集中的資料列編號,或與狀態記錄相關聯的參數集合中的參數編號。 資料列編號和參數數位從 1 開始。 如果此狀態記錄未與資料列編號或參數編號相關聯,則此欄位具有值SQL_NO_ROW_NUMBER。 如果驅動程式無法判斷此記錄相關聯的資料列編號或參數編號,則此欄位具有值SQL_ROW_NUMBER_UNKNOWN。

此欄位的內容只會針對語句控制碼定義。
SQL_DIAG_SERVER_NAME SQLCHAR * 字串,指出診斷記錄所關聯的伺服器名稱。 與使用 SQL_DATA_SOURCE_NAME 選項呼叫 SQLGetInfo 所傳回的值相同。 對於與環境控制碼相關聯的診斷資料結構,以及與任何伺服器無關的診斷資料結構,此欄位是長度為零的字串。
SQL_DIAG_SQLSTATE SQLCHAR * 五個字元的 SQLSTATE 診斷程式代碼。 如需詳細資訊,請參閱 SQLSTATEs
SQL_DIAG_SUBCLASS_ORIGIN SQLCHAR * 字串,其格式和有效值與SQL_DIAG_CLASS_ORIGIN相同,可識別 SQLSTATE 程式碼子類別部分的定義部分。 傳回 「ODBC 3.0」 的 ODBC 特定 SQLSTATES 包含下列專案:

01S00、01S01、01S02、01S06、01S07、07S01、 08S01、21S01、21S02、25S01、25S02、25S03、42S01、42S02、42S11、42S21、42S22、HY095、HY097、HY098、HY099、 HY100、HY101、HY105、HY107、HY109、HY110、HY111、HYT00、HYT01、IM001、IM001、IM003、IM004、IM005、IM006、IM007、IM008、IM010、IM011、IM012。

動態函數位段的值

下表描述SQL_DIAG_DYNAMIC_FUNCTION和SQL_DIAG_DYNAMIC_FUNCTION_CODE的值,這些值會套用至呼叫 SQLExecute SQLExecDirect 所執行的每個 SQL 語句類型。 驅動程式可以將驅動程式定義的值新增至列出的值。

SQL statement

執行


SQL_DIAG_DYNAMIC_FUNCTION


SQL_DIAG_DYNAMIC_FUNCTION_CODE
alter-domain-statement 「ALTER DOMAIN」 SQL_DIAG_ALTER_DOMAIN
alter-table-statement 「ALTER TABLE」 SQL_DIAG_ALTER_TABLE
assertion-definition 「CREATE ASSERTION」 SQL_DIAG_CREATE_ASSERTION
character-set-definition 「CREATE CHARACTER SET」 SQL_DIAG_CREATE_CHARACTER_SET
collation-definition 「CREATE COLLATION」 SQL_DIAG_CREATE_COLLATION
domainn-definition 「CREATE DOMAIN」 SQL_DIAG_CREATE_DOMAIN
create-index-statement 「CREATE INDEX」 SQL_DIAG_CREATE_INDEX
create-table-statement 「CREATE TABLE」 SQL_DIAG_CREATE_TABLE
create-view-statement 「CREATE VIEW」 SQL_DIAG_CREATE_VIEW
cursor-specification 「SELECT CURSOR」 SQL_DIAG_SELECT_CURSOR
delete-statement-positioned 「DYNAMIC DELETE CURSOR」 SQL_DIAG_DYNAMIC_DELETE_CURSOR
delete-statement-searched 「DELETE WHERE」 SQL_DIAG_DELETE_WHERE
drop-assertion-statement 「DROP ASSERTION」 SQL_DIAG_DROP_ASSERTION
drop-character-set-stmt 「DROP CHARACTER SET」 SQL_DIAG_DROP_CHARACTER_SET
drop-collation-statement 「DROP COLLATION」 SQL_DIAG_DROP_COLLATION
drop-domain-statement 「DROP DOMAIN」 SQL_DIAG_DROP_DOMAIN
drop-index-statement 「DROP INDEX」 SQL_DIAG_DROP_INDEX
drop-schema-statement 「DROP SCHEMA」 SQL_DIAG_DROP_SCHEMA
drop-table-statement 「DROP TABLE」 SQL_DIAG_DROP_TABLE
drop-translation-statement 「DROP TRANSLATION」 SQL_DIAG_DROP_TRANSLATION
drop-view-statement 「DROP VIEW」 SQL_DIAG_DROP_VIEW
grantstatement 「GRANT」 SQL_DIAG_GRANT
insert-statement 「INSERT」 SQL_DIAG_INSERT
ODBC-procedure-extension 「CALL」 SQL_DIAG_通話
revoke-statement 「REVOKE」 SQL_DIAG_REVOKE
schema-definition 「CREATE SCHEMA」 SQL_DIAG_CREATE_SCHEMA
translation-definition 「CREATE TRANSLATION」 SQL_DIAG_CREATE_TRANSLATION
update-statement-positioned 「DYNAMIC UPDATE CURSOR」 SQL_DIAG_DYNAMIC_UPDATE_CURSOR
update-statement-searched 「UPDATE WHERE」 SQL_DIAG_UPDATE_WHERE
未知 空字串 SQL_DIAG_UNKNOWN_STATEMENT

狀態記錄的順序

狀態記錄會根據資料列號碼和診斷類型,依序排列。 驅動程式管理員會決定要傳回其產生之狀態記錄的最終順序。 驅動程式會決定要傳回其產生狀態記錄的最終順序。

如果驅動程式管理員和驅動程式都會張貼診斷記錄,驅動程式管理員會負責訂購這些記錄。

如果有兩筆以上的狀態記錄,則記錄的順序會先由資料列編號決定。 下列規則適用于依資料列判斷診斷記錄順序:

  • 未對應至任何資料列的記錄會出現在對應至特定資料列的記錄前面,因為SQL_NO_ROW_NUMBER定義為 -1。

  • 資料列號碼未知的記錄會出現在所有其他記錄前面,因為SQL_ROW_NUMBER_UNKNOWN定義為 -2。

  • 對於所有與特定資料列相關的記錄,記錄會依 [SQL_DIAG_ROW_NUMBER] 欄位中的值排序。 列出受影響第一個資料列的所有錯誤和警告,然後列出下一個資料列的所有錯誤和警告,依此列出。

注意

如果 ODBC 2*.x* 驅動程式傳回 SQLSTATE 01S01(資料列中的錯誤),ODBC 3*.x* 驅動程式不會排序診斷佇列中的狀態記錄,或 SQLSTATE 01 呼叫 SQLExtendedFetch 時 ,ODBC 3*.x* 驅動程式會傳回 ODBC 3*.x* 驅動程式,或 呼叫 SQLSetPos 的資料指標上已與 SQLExtendedFetch 一起 定位的資料指標。

在每個資料列內,或針對未對應至資料列或資料列號碼未知的所有記錄,或針對所有資料列號碼等於SQL_NO_ROW_NUMBER的記錄,列出的第一筆記錄是使用一組排序規則來決定。 在第一筆記錄之後,影響資料列的其他記錄順序未定義。 應用程式無法假設錯誤在第一筆記錄之後的警告之前。 應用程式應該掃描完整的診斷資料結構,以取得未成功呼叫函式的完整資訊。

下列規則可用來判斷資料列內的第一筆記錄。 順位最高的記錄是第一筆記錄。 記錄的來源 (驅動程式管理員、驅動程式、閘道等) 不會在設定記錄順位時考慮。

  • 錯誤 描述錯誤的狀態記錄具有最高的順位。 下列規則會套用至排序錯誤:

    • 指出交易失敗或可能的交易失敗超過所有其他記錄的記錄。

    • 如果兩個或多個記錄描述相同的錯誤條件,則 Open Group CLI 規格(類別 03 到 HZ)所定義的 SQLSTATE 會超過 ODBC 和驅動程式定義的 SQLSTATE。

  • 實作定義的無資料值 描述驅動程式定義的「無資料」值 (類別 02) 的狀態記錄具有第二高順位。

  • 警告 描述警告 (類別 01) 的狀態記錄順位最低。 如果兩筆以上的記錄描述相同的警告條件,則警告 Open Group CLI 規格所定義的 SQLSTATE 與驅動程式定義的 SQLSTATE。

如需下列資訊 請參閱
取得診斷資料結構的多個欄位 SQLGetDiagRec 函式

另請參閱

ODBC API 參考
ODBC 標頭檔