30.7. 动态 SQL

在许多情况下,应用要执行的具体的 SQL 语句在书写应用的时候就已经知道了。 不过,在某些情况下,SQL 语句是在运行时或者由外部的数据提供的。 在这种情况下,我们不能直接在 C 代码嵌入 SQL 语句,但是有个机制可以允许你调用放在一个字串变量里的任何 SQL 语句。

执行任意 SQL 语句最简单的方法是使用 EXECUTE IMMEDIATE 命令。比如:

EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "CREATE TABLE test1 (...);";
EXEC SQL END DECLARE SECTION;

EXEC SQL EXECUTE IMMEDIATE :stmt;

你不能用这个办法执行检索数据的语句(也就是说,SELECT )。

执行任意 SQL 语句的更强大的方法是准备这些语句一次,并且执行这些准备好的语句任意多次。 我们也可以准备一个普遍的语句版本,然后通过替换一些参数, 执行一个特定的版本。在准备语句的时候,在你稍后需要替换参数的地方书写一个问号。比如:

EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "INSERT INTO test1 VALUES(?, ?);";
EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE mystmt FROM :stmt;
 ...
EXEC SQL EXECUTE mystmt USING 42, 'foobar';

如果你在执行的语句返回数值,那么增加一个 INTO 子句:

EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?";
int v1, v2;
VARCHAR v3;
EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE mystmt FROM :stmt;
 ...
EXEC SQL EXECUTE mystmt INTO v1, v2, v3 USING 37;

一个 EXECUTE 命令可以有一个 INTO 子句, 一个 USING 子句,也可以两个都有或者两个都没有。

如果你不再需要已准备好的语句,你应该释放它:

EXEC SQL DEALLOCATE PREPARE name;