SQLPrepare 函数

一致性
引入的版本:ODBC 1.0 标准符合性:ISO 92

总结
SQLPrepare 准备一个 SQL 字符串以供执行。

语法

  
SQLRETURN SQLPrepare(  
     SQLHSTMT      StatementHandle,  
     SQLCHAR *     StatementText,  
     SQLINTEGER    TextLength);  

参数

StatementHandle
[输入]语句句柄。

StatementText
[输入]SQL 文本字符串。

TextLength
[输入]字符形式的 *StatementText 的长度。

返回

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_STILL_EXECUTING、SQL_ERROR或SQL_INVALID_HANDLE。

诊断

当 SQLPrepare 返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可以通过使用 handleType of SQL_HANDLE_STMT 和 StatementHandle 句柄调用 SQLGetDiagRec 来获取关联的 SQLSTATE 值。 下表列出了 SQLPrepare 通常返回的 SQLSTATE 值,并解释此函数上下文中的每个值;表示法“(DM)”位于驱动程序管理器返回的 SQLSTATE 的说明之前。 除非另有说明,否则与每个 SQLSTATE 值关联的返回代码SQL_ERROR。

SQLSTATE 错误 说明
01000 常规警告 特定于驱动程序的信息性消息。 (函数返回SQL_SUCCESS_WITH_INFO。)
01S02 选项值已更改 由于实现工作条件,指定的语句属性无效,因此暂时替换了类似的值。 (可以调用 SQLGetStmtAttr 来确定临时替换的值。替换值对 StatementHandle 有效,直到光标关闭为止。 可更改的语句属性为:SQL_ATTR_CONCURRENCY SQL_ATTR_CURSOR_TYPE SQL_ATTR_KEYSET_SIZE SQL_ATTR_MAX_LENGTH SQL_ATTR_MAX_ROWS SQL_ATTR_QUERY_TIMEOUT SQL_ATTR_SIMULATE_CURSOR

(函数返回SQL_SUCCESS_WITH_INFO。)
08S01 通信链接失败 驱动程序与驱动程序连接到的数据源之间的通信链接在函数完成处理之前失败。
21S01 插入值列表与列列表不匹配 *StatementText 包含 INSERT 语句,要插入的值数与派生表的程度不匹配。
21S02 派生表的程度与列列表不匹配 *StatementText 包含 CREATE VIEW 语句,指定的名称数与查询规范定义的派生表不同。
22018 强制转换规范的字符值无效 *StatementText 包含一个包含文本或参数的 SQL 语句,并且该值与关联的表列的数据类型不兼容。
22019 转义字符无效 argument StatementText 在 WHERE 子句中包含 ESCAPE 的 LIKE词,而 ESCAPE 后面的转义字符长度不等于 1。
22025 无效转义序列 argument StatementText 在 WHERE 子句中包含LIKE 模式值 ESCAPE 转义字符”,模式值中的转义字符后面的字符既不是“%”也不是“_”。
24000 游标状态无效 (DM) 在 StatementHandle 上打开游标,并调用了 SQLFetchSQLFetchScroll

游标在 StatementHandle 上打开,但未调用 SQLFetchSQLFetchScroll
34000 无效的游标名称 *StatementText 包含定位 的 DELETE 或定位 UPDATE,并且由正在准备的语句引用的游标未打开。
3D000 无效的目录名称 StatementText 中指定的目录名称无效。
3F000 无效的架构名称 StatementText 中指定的架构名称无效。
42000 语法错误或访问冲突 *StatementText 包含不可预分析或包含语法错误的 SQL 语句。

*StatementText 包含用户没有所需权限的语句。
42S01 基表或视图已存在 *StatementText 包含 CREATE TABLECREATE VIEW 语句,并且已存在指定的表名或视图名称。
42S02 找不到基表或视图 *StatementText 包含 DROP TABLEDROP VIEW 语句,指定的表名或视图名称不存在。

*StatementText 包含 ALTER TABLE 语句,指定的表名不存在。

*StatementText 包含 CREATE VIEW 语句,查询规范定义的表名或视图名称不存在。

*StatementText 包含 CREATE INDEX 语句,指定的表名不存在。

*StatementText 包含 GRANTREVOKE 语句,指定的表名或视图名称不存在。

*StatementText 包含 SELECT 语句,指定的表名或视图名称不存在。

*StatementText 包含 DELETEINSERTUPDATE 语句,并且指定的表名不存在。

*StatementText 包含 CREATE TABLE 语句,以及约束中指定的表(引用所创建表以外的表)不存在。
42S11 索引已存在 *StatementText 包含 CREATE INDEX 语句,并且已存在指定的索引名称。
42S12 找不到索引 *StatementText 包含 DROP INDEX 语句,指定的索引名称不存在。
42S21 列已存在 *StatementText 包含 ALTER TABLE 语句,ADD 子句中指定的列不唯一或标识基表中的现有列。
42S22 找不到列 *StatementText 包含 CREATE INDEX 语句,列列表中指定的一个或多个列名不存在。

*StatementText 包含 GRANTREVOKE 语句,并且不存在指定的列名。

*StatementText 包含 SELECTDELETEINSERTUPDATE 语句,并且不存在指定的列名。

*StatementText 包含 CREATE TABLE 语句,并且约束中指定的列(引用所创建的表以外的表)不存在。
HY000 常规错误 发生错误:没有特定的 SQLSTATE,也没有定义特定于实现的 SQLSTATE。 *MessageText 缓冲区中 SQLGetDiagRec 返回的错误消息描述错误及其原因。
HY001 内存分配错误 驱动程序无法分配支持执行或完成函数所需的内存。
HY008 操作已取消 StatementHandle 启用了异步处理。 调用了该函数,在完成执行之前,对 StatementHandle 调用 SQLCancel 或 SQLCancelHandle,然后在 StatementHandle再次调用该函数。

调用了函数,在完成执行之前,SQLCancel 或 SQLCancelHandle 从多线程应用程序中的不同线程调用 StatementHandle
HY009 无效使用 null 指针 (DM) StatementText 是空指针。
HY010 函数序列错误 (DM) 为与 StatementHandle 关联的连接句柄调用异步执行函数。 调用 SQLPrepare 函数时,此异步函数仍在执行。

(DM) 为 StatementHandle 调用了 SQLExecuteSQLExecDirectSQLMoreResults,并返回了SQL_PARAM_DATA_AVAILABLE。 在检索所有流式处理参数的数据之前调用此函数。

(DM) 为 StatementHandle 调用异步执行函数(而不是此函数),并在调用此函数时仍在执行。

(DM) 为 StatementHandle 调用了 SQLExecuteSQLExecDirectSQLBulkOperationsSQLSetPos,并返回了SQL_NEED_DATA。 在为所有数据执行参数或列发送数据之前调用此函数。
HY013 内存管理错误 无法处理函数调用,因为基础内存对象无法访问,可能是因为内存条件低。
HY090 字符串或缓冲区长度无效 (DM) 参数 TextLength 小于或等于 0,但不等于SQL_NTS。
HY117 连接因未知事务状态而挂起。 仅允许断开连接和只读函数。 (DM) 有关挂起状态的详细信息,请参阅 SQLEndTran 函数
HYC00 未实现可选功能 定义的游标类型的并发设置无效。

SQL_ATTR_USE_BOOKMARKS语句属性设置为SQL_UB_VARIABLE,SQL_ATTR_CURSOR_TYPE语句属性设置为驱动程序不支持书签的游标类型。
HYT00 已超时 在数据源返回结果集之前过期的超时期限。 超时期限通过 SQLSetStmtAttr 设置,SQL_ATTR_QUERY_TIMEOUT。
HYT01 超过连接超时时间 在数据源响应请求之前,连接超时期限已过期。 连接超时期限通过 SQLSetConnectAttr 设置,SQL_ATTR_CONNECTION_TIMEOUT。
IM001 驱动程序不支持此函数 (DM) 与 StatementHandle 关联的驱动程序不支持该函数。
IM017 在异步通知模式下禁用轮询 每当使用通知模型时,轮询将被禁用。
IM018 尚未调用 SQLCompleteAsync 来完成此句柄上的上一个异步操作。 如果句柄上的上一个函数调用返回SQL_STILL_EXECUTING并且启用通知模式, 则必须在句柄上调用 SQLCompleteAsync 才能执行后期处理并完成操作。

注释

应用程序调用 SQLPrepare 将 SQL 语句发送到数据源进行准备。 有关准备的执行的详细信息,请参阅 “准备执行”。 应用程序可以在 SQL 语句中包含一个或多个参数标记。 若要包含参数标记,应用程序会将问号(?)嵌入到位于适当位置的 SQL 字符串中。 有关参数的信息,请参阅 语句参数

注意

如果应用程序使用 SQLPrepare 准备和 SQLExecute 提交 COMMITROLLBACK 语句,则它不会在 DBMS 产品之间互操作。 若要提交或回滚事务,请调用 SQLEndTran

驱动程序可以修改语句以使用数据源使用的 SQL 形式,然后将其提交到数据源进行准备。 具体而言,驱动程序修改用于定义某些功能的 SQL 语法的转义序列。 (有关 SQL 语句语法的说明,请参阅 ODBC附录 C 中的转义序列:SQL 语法。对于驱动程序,语句句柄类似于嵌入式 SQL 代码中的语句标识符。 如果数据源支持语句标识符,驱动程序可以将语句标识符和参数值发送到数据源。

准备好语句后,应用程序使用语句句柄在后面的函数调用中引用该语句。 通过调用 SQLExecute,可以重新执行与语句句柄关联的已准备语句,直到应用程序通过SQL_DROP选项调用 SQLFreeStmt 释放语句,或者在调用 SQLPrepare、SQLExecDirect 或其中一个目录函数(SQLColumnsSQLTables 等)中使用语句句柄为止。 应用程序准备语句后,可以请求有关结果集格式的信息。 对于某些实现,在 SQLPrepare 之后调用 SQLDescribeColSQLDescribeParam 可能不如在 SQLExecuteSQLExecDirect 之后调用函数那么高效。

当应用程序调用 SQLPrepare 时,某些驱动程序无法返回语法错误或访问冲突。 驱动程序可以处理语法错误和访问冲突、仅处理语法错误或语法错误和访问冲突。 因此,在调用后续相关函数(如 SQLNumResultCols、SQLDescribeCol、SQLColAttributeSQLExecute)时,应用程序必须能够处理这些条件。

根据驱动程序和数据源的功能,在准备好语句时(如果所有参数都已绑定)或执行参数信息(如果所有参数尚未绑定)时,可能会检查参数信息(如数据类型)。 为了获得最大的互操作性,应用程序应取消绑定应用于旧 SQL 语句的所有参数,然后再在同一语句上准备新的 SQL 语句。 这可以防止由于将旧参数信息应用到新语句而导致的错误。

重要

通过显式调用 SQLEndTran 或以自动提交模式提交事务,可能会导致数据源删除连接上所有语句的访问计划。 有关详细信息,请参阅 SQLGetInfo 中的SQL_CURSOR_COMMIT_BEHAVIOR和SQL_CURSOR_ROLLBACK_BEHAVIOR信息类型以及对游标和准备语句的事务的影响。

代码示例

请参阅 SQLBindParameterSQLPutDataSQLSetPos

有关以下内容的信息 请参阅
分配语句句柄 SQLAllocHandle 函数
将缓冲区绑定到结果集中的列 SQLBindCol 函数
将缓冲区绑定到参数 SQLBindParameter 函数
取消语句处理 SQLCancel 函数
执行提交或回滚操作 SQLEndTran 函数
执行 SQL 语句 SQLExecDirect 函数
执行准备的 SQL 语句 SQLExecute 函数
返回受语句影响的行数 SQLRowCount 函数
设置游标名称 SQLSetCursorName 函数

另请参阅

ODBC API 参考
ODBC 头文件