[输入]语句句柄。
SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_NO_DATA、SQL_STILL_EXECUTING、SQL_ERROR或SQL_INVALID_HANDLE。
当
SQLFetch
返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可以通过调用
SQLGetDiagRec 函数
来获取关联的 SQLSTATE 值,该函数的
HandleType
为 SQL_HANDLE_STMT 和
Handle
of
StatementHandle
。 下表列出了
SQLFetch
通常返回的 SQLSTATE 值,并说明了此函数上下文中的每个值:表示法“ (DM) ”位于驱动程序管理器返回的 SQLSTATE 说明之前。 与每个 SQLSTATE 值关联的返回代码SQL_ERROR,除非另有说明。 如果单个列上发生错误,可以使用
diagIdentifier
SQL_DIAG_COLUMN_NUMBER 调用
SQLGetDiagField
,以确定发生错误的列;和
SQLGetDiagField
可以使用 SQL_DIAG_ROW_NUMBER 的
DiagIdentifier
调用,以确定包含该列的行。
对于除 01xxx SQLSTATEs) 以外的所有可返回SQL_SUCCESS_WITH_INFO或SQL_ERROR (的 SQLSTATE,如果多行操作的一行或多行发生错误,则返回SQL_SUCCESS_WITH_INFO;如果单行操作出错,则返回SQL_ERROR。
SQLSTATE
01S07
为列返回的数据已被截断。 对于数值数据类型,数字的小数部分被截断。 对于包含时间分量的时间、时间戳和间隔数据类型,时间的小数部分被截断。
(函数返回 SQL_SUCCESS_WITH_INFO.)
07006
受限数据类型属性冲突
无法将结果集中列的数据值转换为
SQLBindCol
中
TargetType
指定的数据类型。
列 0 与数据类型SQL_C_BOOKMARK绑定,SQL_ATTR_USE_BOOKMARKS 语句属性设置为 SQL_UB_VARIABLE。
列 0 绑定了SQL_C_VARBOOKMARK数据类型,SQL_ATTR_USE_BOOKMARKS 语句属性未设置为 SQL_UB_VARIABLE。
07009
描述符索引无效
驱动程序是不支持
SQLExtendedFetch
的 ODBC 2*.x* 驱动程序,在列绑定中指定的列号为 0。
列 0 已绑定,SQL_ATTR_USE_BOOKMARKS 语句属性设置为 SQL_UB_OFF。
08S01
通信链接失败
在函数完成处理之前,驱动程序与所连接的数据源之间的通信链接失败。
22001
字符串数据,右截断
为列返回的可变长度书签已被截断。
22002
需要指示器变量,但未提供
NULL 数据提取到由
SQLBindCol
(设置StrLen_or_IndPtr
的列,或者由
SQLSetDescField
或
SQLSetDescRec
) 设置的SQL_DESC_INDICATOR_PTR为 null 指针。
22003
数值范围外
将数值作为数值或字符串返回一个或多个绑定列会导致整个 (而不是数字的) 部分被截断。
有关详细信息,请参阅附录 D:
数据类型中的将数据从 SQL 转换为 C
数据类型。
22007
日期/时间格式无效
结果集中的字符列绑定到日期、时间或时间戳 C 结构,列中的值分别为无效的日期、时间或时间戳。
22012
返回了算术表达式中的值,导致除以零。
22015
间隔字段溢出
从确切的数字或间隔 SQL 类型分配给间隔 C 类型会导致前导字段中的重要数字丢失。
将数据提取到间隔 C 类型时,间隔 C 类型中没有 SQL 类型的值表示形式。
22018
强制转换规范的字符值无效
结果集中的字符列绑定到字符 C 缓冲区,并且该列包含缓冲区的字符集中没有表示形式的字符。
C 类型是精确或近似数值、日期时间或间隔数据类型;列的 SQL 类型是字符数据类型;列中的值不是绑定 C 类型的有效文本。
24000
游标状态无效
StatementHandle
处于已执行状态,但没有结果集与
StatementHandle
关联。
40001
序列化失败
执行提取的事务已终止,以防止死锁。
40003
语句完成未知
在执行此函数期间,关联的连接失败,并且无法确定事务的状态。
HY000
发生错误,其中没有特定的 SQLSTATE,也没有定义特定于实现的 SQLSTATE。
SQLGetDiagRec
在
*MessageText
缓冲区中返回的错误消息描述了错误及其原因。
HY001
内存分配错误
驱动程序无法分配支持执行或完成函数所需的内存。
HY008
操作已取消
已为
StatementHandle
启用异步处理。 调用
了 SQLFetch
函数,在它完成执行之前,在
StatementHandle
上调用
了 SQLCancel 或 SQLCancelHandle
。
然后,在
StatementHandle
上再次调用
SQLFetch
函数。
或者,调用
了 SQLFetch
函数,在它完成执行之前,
SqlCancel
或
SQLCancelHandle
是从多线程应用程序中的不同线程在
StatementHandle
上调用的。
HY010
函数序列错误
(DM) 为
与 StatementHandle
关联的连接句柄调用了异步执行的函数。 调用
SQLFetch
函数时,此异步函数仍在执行。
(DM)
SQLExecute
、
SQLExecDirect
或
SQLMoreResults
已为
StatementHandle
调用并返回SQL_PARAM_DATA_AVAILABLE。 此函数是在检索所有流式处理参数的数据之前调用的。
(DM) 指定的
StatementHandle
未处于执行状态。 该函数是在未首先调用
SQLExecDirect
、
SQLExecute
或目录函数的情况下调用的。
(DM) 为
StatementHandle
调用了异步执行的函数 (不是此函数) ,并且调用此函数时仍在执行。
(DM)
SQLExecute
、
SQLExecDirect
、
SQLBulkOperations
或
SQLSetPos
已为
StatementHandle
调用并返回SQL_NEED_DATA。 在为所有数据执行时参数或列发送数据之前调用了此函数。
(DM)
SQLFetch
是在调用
SQLExtendedFetch
之后为
StatementHandle
调用的,在调用具有 SQL_CLOSE 选项的
SQLFreeStmt
之前。
HY013
内存管理错误
无法处理函数调用,因为无法访问基础内存对象,可能是因为内存不足。
HY090
无效的字符串或缓冲区长度
SQL_ATTR_USE_BOOKMARK 语句属性设置为 SQL_UB_VARIABLE,并且列 0 绑定到一个缓冲区,该缓冲区的长度不等于此结果集书签的最大长度。 (此长度在 IRD 的 SQL_DESC_OCTET_LENGTH 字段中提供,可通过调用
SQLDescribeCol
、
SQLColAttribute
或
SQLGetDescField
.)
HY107
行值范围外
使用 SQL_ATTR_CURSOR_TYPE 语句属性指定的值已SQL_CURSOR_KEYSET_DRIVEN,但使用 SQL_ATTR_KEYSET_SIZE 语句属性指定的值大于 0 且小于使用 SQL_ATTR_ROW_ARRAY_SIZE 语句属性指定的值。
HY117
由于未知的事务状态,连接已挂起。 仅允许断开连接和只读函数。
(DM) 有关挂起状态的详细信息,请参阅
SQLEndTran 函数
。
HYC00
未实现可选功能
驱动程序或数据源不支持由
SQLBindCol
中的
TargetType
和相应列的 SQL 数据类型的组合指定的转换。
HYT00
超时时间已到
查询超时期限在数据源返回请求的结果集之前过期。 超时期限是通过 SQLSetStmtAttr SQL_ATTR_QUERY_TIMEOUT设置的。
HYT01
超过连接超时时间
在数据源响应请求之前,连接超时期限已过期。 连接超时期限是通过
SQLSetConnectAttr
SQL_ATTR_CONNECTION_TIMEOUT设置的。
IM001
驱动程序不支持此函数
(DM) 与
StatementHandle
关联的驱动程序不支持 函数。
IM017
在异步通知模式下禁用轮询
每当使用通知模型时,轮询都将被禁用。
IM018
尚未调用
SQLCompleteAsync
来完成此句柄上的上一个异步操作。
如果句柄上的上一个函数调用返回SQL_STILL_EXECUTING并且启用了通知模式,则必须在句柄上调用
SQLCompleteAsync
以执行后期处理并完成操作。
SQLFetch
返回结果集中的下一个行集。 它只能在结果集存在时调用:即,在创建结果集的调用之后,以及关闭该结果集上的光标之前。 如果绑定了任何列,则返回这些列中的数据。 如果应用程序指定了指向行状态数组或缓冲区的指针,在该数组中返回提取的行数,
SQLFetch
也会返回此信息。 对
SQLFetch
的调用可以与对
SQLFetchScroll
的调用混合,但不能与对
SQLExtendedFetch
的调用混合。 有关详细信息,请参阅
提取数据行
。
如果 ODBC 3*.x* 应用程序适用于 ODBC 2*.x* 驱动程序,驱动程序管理器会将
SQLFetch
调用映射到支持
SQLExtendedFetch
的 ODBC 2*.x* 驱动程序的
SQLExtendedFetch
。 如果 ODBC 2*.x* 驱动程序不支持
SQLExtendedFetch
,驱动程序管理器会将
SQLFetch
调用映射到 ODBC 2*.x* 驱动程序中的
SQLFetch
,该驱动程序只能提取一行。
有关详细信息,请参阅附录 G:向后兼容性驱动程序指南中的
块游标、可滚动
游标和向后兼容性。
创建结果集时,光标位于结果集开始之前。
SQLFetch
提取下一个行集。 它等效于调用
将 FetchOrientation
设置为 SQL_FETCH_NEXT
的 SQLFetchScroll
。 有关游标的详细信息,请参阅
游标
和
块游标
。
SQL_ATTR_ROW_ARRAY_SIZE 语句属性指定行集中的行数。 如果
SQLFetch
提取的行集与结果集的末尾重叠,
则 SQLFetch
将返回部分行集。 也就是说,如果 S + R - 1 大于 L,其中 S 是要提取的行集的起始行,R 是行集大小,L 是结果集中的最后一行,则只有行集的第一个 L - S + 1 行有效。 其余行为空,状态为SQL_ROW_NOROW。
SQLFetch
返回后,当前行是行集的第一行。
下表中列出的规则根据本节第二个表中列出的条件描述了调用
SQLFetch
后的游标定位。
新行集的第一行
在绑定列中返回数据
当 SQLFetch
返回每一行时,它会将每个绑定列的数据放入绑定到该列的缓冲区中。 如果未绑定任何列,
SQLFetch
不会返回任何数据,但会向前移动块光标。 仍可使用
SQLGetData
检索数据。 如果游标是多行游标 (即SQL_ATTR_ROW_ARRAY_SIZE大于 1) ,则仅当使用
SQL_GETDATA_EXTENSIONS InfoType
调用
SQLGetInfo
时返回SQL_GD_BLOCK时,才能调用
SQLGetData
。 (有关详细信息,请参阅
SQLGetData
.)
对于行中的每个绑定列,
SQLFetch
将执行以下操作:
将长度/指示器缓冲区设置为SQL_NULL_DATA,如果数据为 NULL,则继续下一列。 如果数据为 NULL 且未绑定长度/指示器缓冲区,
SQLFetch
将返回 SQLSTATE 22002 (指示符变量,但未为行提供) ,然后继续下一行。 有关如何确定长度/指示器缓冲区的地址的信息,请参阅
SQLBindCol
中的“缓冲区地址”。
如果列的数据不是 NULL,
SQLFetch
将继续执行步骤 2。
如果 SQL_ATTR_MAX_LENGTH 语句属性设置为非零值,并且列包含字符或二进制数据,则数据将被截断为SQL_ATTR_MAX_LENGTH个字节。
SQL_ATTR_MAX_LENGTH 语句属性旨在减少网络流量。 它通常由数据源实现,数据源在通过网络返回数据之前会截断数据。 不需要驱动程序和数据源来支持它。 因此,若要保证数据被截断为特定大小,应用程序应分配该大小的缓冲区,并在
SQLBindCol
的
cbValueMax
参数中指定大小。
将数据转换为
SQLBindCol
中
TargetType
指定的类型。
如果数据已转换为可变长度的数据类型(如字符或二进制),
SQLFetch
会检查数据的长度是否超过数据缓冲区的长度。 如果字符数据的长度 (包括 null 终止字符) 超过数据缓冲区的长度,
SQLFetch
会将数据截断为数据缓冲区的长度减去 null 终止字符的长度。 然后,它会为 null 终止数据。 如果二进制数据的长度超过数据缓冲区的长度,
SQLFetch
会将其截断为数据缓冲区的长度。 数据缓冲区的长度在
SQLBindCol
中使用
BufferLength
指定。
SQLFetch
永远不会截断转换为固定长度数据类型的数据;它始终假定数据缓冲区的长度是数据类型的大小。
将转换后的 (并可能截断) 数据放入数据缓冲区中。 有关如何确定数据缓冲区地址的信息,请参阅
SQLBindCol
中的“缓冲区地址”。
将数据的长度放入长度/指示器缓冲区中。 如果指示器指针和长度指针都设置为与调用
SQLBindCol
) 相同的缓冲区 (,则会在缓冲区中写入有效数据的长度,SQL_NULL_DATA将写入 NULL 数据的缓冲区中。 如果未绑定长度/指示器缓冲区,
SQLFetch
不会返回长度。
对于字符或二进制数据,这是转换后和截断之前的数据长度,因为数据缓冲区太小。 如果驱动程序无法确定转换后的数据长度(有时使用长数据的情况),则会将长度设置为SQL_NO_TOTAL。 如果由于 SQL_ATTR_MAX_LENGTH 语句属性而截断了数据,则此属性的值将放在长度/指示器缓冲区中,而不是实际长度 。 这是因为此属性旨在截断转换前服务器上的数据,因此驱动程序无法确定实际长度。
对于所有其他数据类型,这是转换后的数据长度;也就是说,它是数据转换为的类型的大小。
有关如何确定长度/指示器缓冲区的地址的信息,请参阅
SQLBindCol
中的“缓冲区地址”。
例如,如果在转换过程中截断数据而不丢失有效数字 (,则实数 1.234 在转换) 时被截断为整数 1,
SQLFetch
将返回 SQLSTATE 01S07 (小数截断) 和SQL_SUCCESS_WITH_INFO。 例如,如果由于数据缓冲区的长度太小而截断了数据, (字符串“abcdef”将放入 4 字节缓冲区) ,
SQLFetch
将返回 SQLSTATE 01004 (数据截断) 和SQL_SUCCESS_WITH_INFO。 如果由于 SQL_ATTR_MAX_LENGTH 语句属性而截断数据,
SQLFetch
将返回SQL_SUCCESS,并且不返回 SQLSTATE 01S07 (小数截断) 或 SQLSTATE 01004 (数据截断) 。 例如,如果在转换过程中数据被截断并丢失有效数字 (, 如果将大于 100,000 的SQL_INTEGER值转换为SQL_C_TINYINT) ,
则 SQLFetch
返回 SQLSTATE 22003 (超出范围) 的数值,如果行集大小为 1) SQL_ERROR (;如果行集大小大于 1) ,则SQL_SUCCESS_WITH_INFO (。
如果 SQLFetch 或
SQLFetchScroll
不返回SQL_SUCCESS或SQL_SUCCESS_WITH_INFO,则
未定义绑定数据缓冲区的内容和长度/指示器缓冲区。
行状态数组
行状态数组用于返回行集中每一行的状态。 此数组的地址是使用 SQL_ATTR_ROW_STATUS_PTR 语句属性指定的。 数组由应用程序分配,并且必须具有SQL_ATTR_ROW_ARRAY_SIZE 语句属性所指定的元素数。 其值由
SQLFetch
、
SQLFetchScroll
和
SQLBulkOperations
或
SQLSetPos
(设置,除非在游标由
SQLExtendedFetch
) 定位后调用它们。 如果 SQL_ATTR_ROW_STATUS_PTR 语句属性的值为 null 指针,则这些函数不会返回行状态。
如果
SQLFetch
或
SQLFetchScroll
不返回SQL_SUCCESS或SQL_SUCCESS_WITH_INFO,则未定义行状态数组缓冲区的内容。
以下值在行状态数组中返回。
行状态数组值
SQL_ROW_UPDATED[1]、[2]和 [3]
该行已成功提取,并且自上次从此结果集中提取以来已更改。 如果再次从此结果集中提取行或由
SQLSetPos
刷新,则状态将更改为行的新状态。
SQL_ROW_DELETED[3]
自上次从此结果集中提取行以来,该行已被删除。
SQL_ROW_ADDED[4]
该行由
SQLBulkOperations
插入。 如果行再次从此结果集中提取或由
SQLSetPos
刷新,则其状态为SQL_ROW_SUCCESS。
SQL_ROW_NOROW
行集与结果集的末尾重叠,并且未返回与行状态数组的此元素对应的行。
[1] 对于键集、混合游标和动态游标,如果更新了键值,则数据行被视为已删除并添加了一个新行。
[2] 某些驱动程序无法检测数据更新,因此无法返回此值。 为了确定驱动程序是否可以检测重新引用行的更新,应用程序使用 SQL_ROW_UPDATES 选项调用
SQLGetInfo
。
[3]
仅当 SQLFetch 与对 SQLFetchScroll
的调用混合时,
SQLFetch
才能返回此值。 这是因为
SQLFetch
在结果集中向前移动,并且当它以独占方式使用时,不会重新引用任何行。 由于未重新生成任何行,
因此 SQLFetch
不会检测对以前提取的行所做的更改。 但是,如果
SQLFetchScroll
将游标置于任何以前提取的行之前,并且
SQLFetch
用于提取这些行,
则 SQLFetch
可以检测对这些行所做的任何更改。
[4] 仅由 SQLBulkOperations 返回。 未由
SQLFetch
或
SQLFetchScroll
设置。
提取的行缓冲区
提取的行缓冲区用于返回提取的行数,包括那些由于提取时出错而未返回任何数据的行。 换句话说,它是行状态数组中的值未SQL_ROW_NOROW的行数。 此缓冲区的地址是使用 SQL_ATTR_ROWS_FETCHED_PTR 语句属性指定的。 缓冲区由应用程序分配。 它由
SQLFetch
和
SQLFetchScroll
设置。 如果 SQL_ATTR_ROWS_FETCHED_PTR 语句属性的值为空指针,则这些函数不会返回提取的行数。 若要确定结果集中当前行的编号,应用程序可以使用 SQL_ATTR_ROW_NUMBER 属性调用
SQLGetStmtAttr
。
如果
SQLFetch
或
SQLFetchScroll
不返回SQL_SUCCESS或SQL_SUCCESS_WITH_INFO,则提取缓冲区的行的内容是未定义的,除非返回SQL_NO_DATA,在这种情况下,提取缓冲区中的行值设置为 0。
错误和警告可以应用于单个行或整个函数。 有关诊断记录的详细信息,请参阅
诊断
和
SQLGetDiagField
。
有关整个函数的错误和警告
如果错误适用于整个函数,例如 SQLSTATE HYT00 (超时已过期) 或 SQLSTATE 24000 (游标状态) 无效,
SQLFetch
将返回SQL_ERROR和适用的 SQLSTATE。 行集缓冲区的内容未定义,游标位置保持不变。
如果警告应用于整个函数,
SQLFetch
将返回SQL_SUCCESS_WITH_INFO和适用的 SQLSTATE。 应用于整个函数的警告的状态记录在应用于单个行的状态记录之前返回。
单个行中的错误和警告
如果错误 (SQLSTATE 22012 (除以零) ) 或警告 ((如 SQLSTATE 01004 (数据截断) ) )应用于单行,
SQLFetch
将执行以下操作:
将行状态数组的相应元素设置为SQL_ROW_ERROR错误或警告SQL_ROW_SUCCESS_WITH_INFO。
添加零个或多个状态记录,这些记录包含错误或警告的 SQLSTATE。
设置状态记录中的行号和列号字段。 如果
SQLFetch
无法确定行号或列号,则分别将该数字设置为SQL_ROW_NUMBER_UNKNOWN或SQL_COLUMN_NUMBER_UNKNOWN。 如果状态记录不适用于特定列,
SQLFetch
会将列号设置为SQL_NO_COLUMN_NUMBER。
SQLFetch
继续提取行,直到提取行集中的所有行。 它返回SQL_SUCCESS_WITH_INFO,除非行集的每一行都发生错误 (不包括状态为SQL_ROW_NOROW) 的行,在这种情况下,它将返回SQL_ERROR。 具体而言,如果行集大小为 1 且该行中出现错误,
SQLFetch
将返回SQL_ERROR。
SQLFetch
按行号顺序返回状态记录。 也就是说,如果有任何) ,它将返回未知行 (的所有状态记录;接下来,它将返回第一行 ((如果有任何) )的所有状态记录,然后返回第二行的所有状态记录 ((如果有任何) )等。 每行的状态记录根据对状态记录进行排序的正常规则进行排序;有关详细信息,请参阅
SQLGetDiagField
中的“状态记录序列”。
描述符和 SQLFetch
以下部分介绍
SQLFetch
如何与描述符交互。
驱动程序不会基于
SQLFetch
的参数设置任何描述符字段。
其他描述符字段
SQLFetch
使用以下描述符字段。
描述符字段
Desc.
还可以通过
SQLSetDescField
设置所有描述符字段。
单独的长度和指示器缓冲区
应用程序可以绑定一个或两个单独的缓冲区,这些缓冲区可用于保存长度和指示器值。 当应用程序调用
SQLBindCol
时,驱动程序会将 ARD 的SQL_DESC_OCTET_LENGTH_PTR和SQL_DESC_INDICATOR_PTR字段设置为同一地址,该地址在
StrLen_or_IndPtr
参数中传递。 当应用程序调用
SQLSetDescField
或
SQLSetDescRec
时,它可以将这两个字段设置为不同的地址。
SQLFetch
确定应用程序是否指定了单独的长度和指示器缓冲区。 在这种情况下,当数据不为 NULL 时,
SQLFetch
会将指示器缓冲区设置为 0,并返回长度缓冲区中的长度。 当数据为 NULL 时,
SQLFetch
会将指示器缓冲区设置为SQL_NULL_DATA,并且不会修改长度缓冲区。
请参阅
SQLBindCol
、
SQLColumns
、
SQLGetData
和
SQLProcedures
。
有关以下方面的信息