在很多情况下,一个应用必须执行的特定 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;
执行任意 SQL 语句的一种更强大的方式是
只对它做一次预备,然后按照你的意愿多次执行预备好的语句。
也可以预备语句的一个通用版本,
然后通过替换参数来执行它的特定版本。
准备语句时,在希望稍后替换参数的位置写上问号
?:
当你不再需要某个已准备语句时,应当释放它:
EXEC SQL DEALLOCATE PREPARE name;
要执行一条只有单个结果行的 SQL 语句,
可以使用 EXECUTE。
要保存结果,需要添加一个 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;
如果预期一个查询会返回多于一个结果行, 则应当像下面的示例那样使用游标。 (关于游标的更多细节见 Section 34.3.2。)
EXEC SQL BEGIN DECLARE SECTION;
char stmt[80];
int v1;
VARCHAR v2;
EXEC SQL END DECLARE SECTION;
strcpy(stmt, "SELECT a, b FROM test1 WHERE a > ?");
EXEC SQL PREPARE mystmt FROM :stmt;
EXEC SQL DECLARE cursor1 CURSOR FOR mystmt;
EXEC SQL OPEN cursor1 USING 37;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH cursor1 INTO :v1, :v2;
...
}
EXEC SQL CLOSE cursor1;