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时,可以通过调用 SQLGetDiagRec 来获取关联的 SQLSTATE 值,该 SQLGetDiagRecHandleType 为 SQL_HANDLE_STMT, 句柄StatementHandle。 下表列出了 SQLPrepare 通常返回的 SQLSTATE 值,并说明了此函数上下文中的每个值:表示法“ (DM) ”位于驱动程序管理器返回的 SQLSTATEs 说明之前。 与每个 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 转义字符无效 参数 StatementTextWHERE 子句中包含一个带有 ESCAPELIKE 谓词,而 ESCAPE 后面的转义字符的长度不等于 1。
22025 转义序列无效 参数 StatementTextWHERE 子句中包含“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 上再次调用该函数。

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

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

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

(DM) SQLExecuteSQLExecDirectSQLBulkOperationsSQLSetPos 已为 StatementHandle 调用并返回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 Grammar.) 对于驱动程序,语句句柄类似于嵌入式 SQL 代码中的语句标识符。 如果数据源支持语句标识符,驱动程序可以将语句标识符和参数值发送到数据源。

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

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

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

重要

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

代码示例

请参阅 SQLBindParameterSQLPutDataSQLSetPos

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

另请参阅

ODBC API 参考
ODBC 头文件