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 感知。

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

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

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

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:HandleTypeHandle 指示的句柄不是有效的句柄。

  • 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. 当函数调用返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时获取特定错误或警告信息(或 SQLBrowseConnect 函数的SQL_NEED_DATA)。

  2. 若要通过调用 SQLExecuteSQLExecDirectSQLBulkOperationsSQLSetPos(从SQL_DIAG_ROW_COUNT标头字段)或确定当前打开的游标中存在的行数,确定数据源中受影响的行数,请确定数据源中受影响的行数。 如果驱动程序可以提供此信息(来自SQL_DIAG_CURSOR_ROW_COUNT标头字段)。

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

每次调用 ODBC 函数时,任何 ODBC 函数都可以发布零个或多个诊断记录,因此应用程序可以在任何 ODBC 函数调用后调用 SQLGetDiagField。 任何一次都可以存储的诊断记录数没有限制。 SQLGetDiagField 仅检索最近与 Handle 参数中指定的诊断数据结构关联的诊断信息。 如果应用程序调用非 SQLGetDiagFieldSQLGetDiagRec以外的 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 参数指示句柄 的句柄类型。

对于环境、连接、语句和描述符句柄,无法返回某些标头和记录字段。 以下“标头字段”和“记录字段”部分中指示字段不适用的句柄。

如果 SQL_HANDLE_ENV HandleTypeHandle 可以是共享环境句柄或非共享环境句柄。

不应将特定于驱动程序的标头诊断字段与环境句柄相关联。

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

记录字段

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

DiagIdentifier 返回类型 返回
SQL_DIAG_CLASS_ORIGIN SQLCHAR * 一个字符串,指示定义此记录中 SQLSTATE 值的类部分的文档。 对于 Open Group 和 ISO 调用级别接口定义的所有 SQLSTATE,其值为“ISO 9075”。 对于特定于 ODBC 的 SQLSTATE(其 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的值,这些值适用于调用 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
断言定义 “CREATE ASSERTION” SQL_DIAG_CREATE_ASSERTION
字符集定义 “CREATE CHARACTER SET” SQL_DIAG_CREATE_CHARACTER_SET
排序规则定义 “CREATE COLLATION” SQL_DIAG_CREATE_COLLATION
域定义 “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
游标规范 “SELECT CURSOR” SQL_DIAG_SELECT_CURSOR
delete-statement 定位 “动态删除游标” 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
授权陈述 “GRANT” SQL_DIAG_GRANT
insert-statement “INSERT” SQL_DIAG_INSERT
ODBC-procedure-extension “CALL” SQL_DIAG_呼叫
revoke-statement “REVOKE” SQL_DIAG_REVOKE
架构定义 “CREATE SCHEMA” SQL_DIAG_CREATE_SCHEMA
翻译定义 “创建翻译” SQL_DIAG_CREATE_TRANSLATION
update-statement 定位 “动态更新游标” 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 01S01(行错误)由 ODBC 2*.x* 驱动程序返回,或者 SQLSTATE 01S01(行错误)返回,则 ODBC 3*.x* 驱动程序管理器不会对诊断队列中的状态记录进行排序 调用 SQLExtendedFetch 时 ODBC 3*.x* 驱动程序,或者在 SQLSetPos 的游标上调用 SQLExtendedFetch

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

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

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

    • 指示事务失败或可能的事务失败的记录会退出所有其他记录。

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

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

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

有关
获取诊断数据结构的多个字段 SQLGetDiagRec 函数

另请参阅

ODBC API 参考
ODBC 头文件