准备好的语句不是这样工作的,至少在我所知道的主要 DBMS 中不是这样。我的意思是,在 Go 中,对由以下方法实现的准备好的语句的支持database/sql
司机应该使用底层 DBMS 提供的相应设施(如果与其接口的数据库引擎未提供驱动程序可能会选择模拟此类支持)。
现在,在我熟悉的所有 DBMS 中,准备好的语句的整体思想是对其进行处理once由DB引擎并缓存;这里的“处理”意味着语法检查,编译成一些特定于数据库的内部表示并计算出其执行计划。从术语“编译”来看,该语句的text只处理一次,然后每次调用准备好的语句实际上只是告诉服务器“这是我之前提供给您的准备好的语句的 ID,这是用于它包含的占位符的实际参数列表”。这就像编译一个 Go 程序,然后使用不同的命令行标志连续多次调用它。
So the solution you have come up with is correct: if you want to mess with the statement text between invocation then by all means use client-side text manipulations1 but do not attempt to use the result of it as a prepared statement unless you really intend to execute the resulting text more than once.
可能会更清楚:您最初尝试准备类似的东西
SELECT a, b FROM foo WHERE a IN (?)
据说您尝试为此提供一组值时失败IN (?)
占位符,因为需要逗号来指定多个值是语法,而不是值的一部分。
我觉得准备一些东西应该还是可以的
SELECT a, b FROM foo WHERE a IN (?, ?, ?)
因为它并没有违反这条规则。并不是说它是适合您的解决方案......
也可以看看this http://dev.mysql.com/doc/refman/5.0/en/mysql-stmt-prepare.html and this http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html— 研究后者将允许您直接在 MySQL 客户端中使用准备好的语句。
1 Some engines provide for server-side SQL generation with subsequent execution of the generated text.