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 驱动程序中开发Connection-Pool感知

Handle
[输入]诊断数据结构的句柄,由 HandleType 指示的类型。 如果 HandleType SQL_HANDLE_ENV, 则 Handle 可以是共享或非共享环境句柄。

RecNumber
[输入]指示应用程序从中查找信息的状态记录。 状态记录从 1 开始编号。 如果 DiagIdentifier 参数指示诊断标头的任何字段,则忽略 RecNumber 。 否则,它应大于 0。

DiagIdentifier
[输入]指示要返回其值的诊断字段。 有关详细信息,请参阅“注释”中的“DiagIdentifier Argument”部分。

DiagInfoPtr
[输出]指向要在其中返回诊断信息的缓冲区的指针。 数据类型取决于 DiagIdentifier 的值。 如果 DiagInfoPtr 是整数类型,应用程序应使用 SQLULEN 缓冲区,并在调用此函数之前将值初始化为 0,因为某些驱动程序可能只写入较低 32 位或 16 位的缓冲区,并保留高阶位不变。

如果 DiagInfoPtr 为 NULL, 则 StringLengthPtr 仍将返回总字节数 (不包括字符数据的 null 终止字符,) DiagInfoPtr 指向的缓冲区中可返回。

BufferLength
[输入]如果 DiagIdentifier 是 ODBC 定义的诊断,并且 DiagInfoPtr 指向字符串或二进制缓冲区,则此参数应为 *DiagInfoPtr 的长度。 如果 DiagIdentifier 是 ODBC 定义的字段,并且 *DiagInfoPtr 是整数,则忽略 BufferLength 。 如果 *DiagInfoPtr 中的值是调用 SQLGetDiagFieldW) 时 (的 Unicode 字符串, 则 BufferLength 参数必须是偶数。

如果 DiagIdentifier 是驱动程序定义的字段,则应用程序通过设置 BufferLength 参数向驱动程序管理器指示该字段的性质。 BufferLength 可以具有以下值:

  • 如果 DiagInfoPtr 是指向字符串的指针, 则 BufferLength 是字符串的长度或SQL_NTS。

  • 如果 DiagInfoPtr 是指向二进制缓冲区的指针,则应用程序会将SQL_LEN_BINARY_ATTR (长度 的结果) 宏放在 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 没有诊断记录,则函数还会返回任何正 RecNumber 的SQL_NO_DATA。

注释

应用程序通常调用 SQLGetDiagField 来实现以下三个目标之一:

  1. 在函数调用返回 SQLBrowseConnect 函数) SQL_ERROR、SQL_SUCCESS_WITH_INFO (或SQL_NEED_DATA时获取特定的错误或警告信息。

  2. 若要确定数据源中在执行插入、删除或更新操作时受影响的行数,请从SQL_DIAG_ROW_COUNT标头字段) 调用 SQLExecuteSQLExecDirectSQLBulkOperationsSQLSetPos (,或者确定当前打开游标中存在的行数(如果驱动程序可以从SQL_DIAG_CURSOR_ROW_COUNT标头字段) 提供此信息 ()。

  3. 确定通过调用 SQLExecDirectSQLExecute (从 SQL_DIAG_DYNAMIC_FUNCTION 和 SQL_DIAG_DYNAMIC_FUNCTION_CODE 标头字段) 执行的函数。

任何 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 将生成 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* 应用程序只能使用 diagIdentifier 参数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 来调用 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位。

此字段的内容仅为语句句柄定义,并且仅在调用 SQLExecuteSQLExecDirectSQLMoreResults 之后定义。 调用 SQLGetDiagField 时,除语句句柄外,使用 diagIdentifier SQL_DIAG_CURSOR_ROW_COUNT 将返回SQL_ERROR。
SQL_DIAG_DYNAMIC_FUNCTION SQLCHAR * 这是一个字符串,用于描述基础函数执行的 SQL 语句。 (有关特定值,请参阅本节后面的“动态函数字段的值”。) 此字段的内容仅针对语句句柄定义,并且仅在调用 SQLExecuteSQLExecDirectSQLMoreResults 之后定义。 在语句句柄以外的其他语句上调用具有 SQL_DIAG_DYNAMIC_FUNCTION diagIdentifierSQLGetDiagField 将返回SQL_ERROR。 在调用 SQLExecute 或 SQLExecDirect 之前,此字段的值未定义。
SQL_DIAG_DYNAMIC_FUNCTION_CODE SQLINTEGER 这是一个数字代码,用于描述由基础函数执行的 SQL 语句。 (请参阅本节后面的“动态函数字段的值”,了解特定 value。) 此字段的内容仅针对语句句柄定义,并且仅在调用 SQLExecuteSQLExecDirectSQLMoreResults 之后定义。 使用除语句句柄以外的其他语句的 DiagIdentifier SQL_DIAG_DYNAMIC_FUNCTION_CODE 调用 SQLGetDiagField 将返回SQL_ERROR。 在调用 SQLExecute 或 SQLExecDirect 之前,此字段的值未定义。
SQL_DIAG_NUMBER SQLINTEGER 可用于指定句柄的状态记录数。
SQL_DIAG_RETURNCODE SQLRETURN 返回函数返回的代码。 有关返回代码的列表,请参阅 返回代码。 驱动程序不必实现SQL_DIAG_RETURNCODE;它始终由驱动程序管理器实现。 如果尚未对 Handle 调用任何函数,则将为SQL_DIAG_RETURNCODE返回SQL_SUCCESS。
SQL_DIAG_ROW_COUNT SQLLEN SQLExecute、SQLExecDirectSQLBulkOperationsSQLSetPos 执行的插入、删除或更新影响的行数。 在执行 游标规范 后,它是驱动程序定义的。 此字段的内容仅为语句句柄定义。 使用除语句句柄以外的其他语句句柄上的 diagIdentifier SQL_DIAG_ROW_COUNT 调用 SQLGetDiagField 将返回SQL_ERROR。 此字段中的数据也会在 SQLRowCountRowCountPtr 参数中返回。 此字段中的数据在每次非诊断函数调用后重置,而 SQLRowCount 返回的行计数保持不变,直到语句重新设置为已准备或已分配状态。

记录字段

下表中列出的记录字段可以包含在 DiagIdentifier 参数中。

DiagIdentifier 返回类型 返回
SQL_DIAG_CLASS_ORIGIN SQLCHAR * 一个字符串,指示定义此记录中 SQLSTATE 值的类部分的文档。 对于开放组和 ISO 调用级别接口定义的所有 SQLSTATE,其值为“ISO 9075”。 对于特定于 ODBC 的 SQLSTATEs (SQLSTATE 类为“IM”) 的所有 SQLSTATEs,其值为“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、42S12、42S22、HY095、HY097、HY098、HY099、 HY100、HY101、HY105、HY107、HY109、HY110、HY111、HYT00、HYT01、IM001、IM002、IM003、IM004、IM005、IM006、IM007、IM008、IM010、IM011、IM012。

动态函数字段的值

下表描述了SQL_DIAG_DYNAMIC_FUNCTION和SQL_DIAG_DYNAMIC_FUNCTION_CODE的值,这些值适用于通过调用 SQLExecuteSQLExecDirect 执行的每种类型的 SQL 语句。 驱动程序可以将驱动程序定义的值添加到列出的值。

SQL 语句

已执行
的值

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 断言” 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 “动态删除光标” SQL_DIAG_DYNAMIC_DELETE_CURSOR
delete-statement-searched “DELETE WHERE” SQL_DIAG_DELETE_WHERE
drop-assertion-statement “DROP 断言” 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 “动态更新游标” 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 (行) 错误,或者 SQLSTATE 01S 返回,则 ODBC 3*.x* 驱动程序管理器不会对诊断队列中的状态记录进行排序 01 (当调用 SQLExtendedFetch 或在使用 SQLExtendedFetch 定位的游标上调用 SQLSetPos 时,ODBC 3*.x* 驱动程序会返回行) 错误。

在每一行中,或者对于与某行不对应或行号未知的所有记录,或者对于行号等于SQL_NO_ROW_NUMBER的所有记录,列出的第一条记录使用一组排序规则确定。 在第一条记录之后,影响行的其他记录的顺序是不确定的。 应用程序不能假定错误在第一条记录之后先于警告。 应用程序应扫描完整的诊断数据结构,以获取有关函数调用失败的完整信息。

以下规则用于确定行中的第一条记录。 排名最高的记录是第一条记录。 排名记录时,不考虑记录源 (驱动程序管理器、驱动程序、网关等) 。

  • 错误 描述错误的状态记录的排名最高。 以下规则适用于对错误进行排序:

    • 指示事务失败或可能事务失败的记录将超过所有其他记录。

    • 如果两条或更多条记录描述了相同的错误条件,则开放组 CLI 规范定义的 SQLSTATE (类 03 到 HZ) 超过 ODBC 和驱动程序定义的 SQLSTATE。

  • 实现定义的无数据值 描述驱动程序定义的无数据值的状态记录 (类 02) 具有第二高的排名。

  • 警告 描述 (类 01) 警告的状态记录的排名最低。 如果两条或更多条记录描述了相同的警告条件,则开放组 CLI 规范定义的警告 SQLSTATEs 将超过 ODBC 定义的 SQLSTATEs 和驱动程序定义的 SQLSTATEs。

有关以下方面的信息 请参阅
获取诊断数据结构的多个字段 SQLGetDiagRec 函数

另请参阅

ODBC API 参考
ODBC 头文件