🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 33.3\. 运行SQL命令 在嵌入的SQL应用中可以运行任何SQL命令。下面是一些如何使用它们的例子。 ## 33.3.1\. 执行SQL语句 创建一个表: ``` EXEC SQL CREATE TABLE foo (number integer, ascii char(16)); EXEC SQL CREATE UNIQUE INDEX num1 ON foo(number); EXEC SQL COMMIT; ``` 插入一行: ``` EXEC SQL INSERT INTO foo (number, ascii) VALUES (9999, 'doodad'); EXEC SQL COMMIT; ``` 删除一行: ``` EXEC SQL DELETE FROM foo WHERE number = 9999; EXEC SQL COMMIT; ``` 更新: ``` EXEC SQL UPDATE foo SET ascii = 'foobar' WHERE number = 9999; EXEC SQL COMMIT; ``` 可以通过`EXEC SQL`直接执行返回一个结果行的`SELECT` 语句。为了处理多行结果集,应用程序必须使用游标; 参阅[Section 33.3.2](#calibre_link-1994)。(特殊情况下,应用程序可以一次读取多行到数组宿主变量中; 参阅[Section 33.4.4.3.1](#calibre_link-1995)。) 单行select: ``` EXEC SQL SELECT foo INTO :FooBar FROM table1 WHERE ascii = 'doodad'; ``` 同时,可以使用`SHOW`命令检索配置参数: ``` EXEC SQL SHOW search_path INTO :var; ``` 形如`:``_something_` 这样的记号是_宿主变量_,也就是说,他们指向C程序中的变量。 在[Section 33.4](#calibre_link-1993)中有解释。 ## 33.3.2\. 使用游标 为了检索出多行的结果集,应用程序必须声明一个游标并且从游标中抓取每一行。 使用游标的步骤如下:声明一个游标,打开它,从游标中抓取一行,重复,最后关闭它。 使用游标选择: ``` EXEC SQL DECLARE foo_bar CURSOR FOR SELECT number, ascii FROM foo ORDER BY ascii; EXEC SQL OPEN foo_bar; EXEC SQL FETCH foo_bar INTO :FooBar, DooDad; ... EXEC SQL CLOSE foo_bar; EXEC SQL COMMIT; ``` 关于游标声明的更多细节,请参阅[DECLARE](#calibre_link-25),关于 `FETCH`命令的细节请参阅[FETCH](#calibre_link-74)。 > **Note:** ECPG `DECLARE`命令实际上不会造成语句被发送到PostgreSQL后端。 当执行`OPEN`命令时, 在后端(使用后端的`DECLARE`命令)打开游标。 ## 33.3.3\. 管理事务 在缺省模式下,语句只有在`EXEC SQL COMMIT` 发出的时候才提交, 嵌入的SQL接口也支持事务的自动提交(类似libpq的行为), 方法是通过给`ecpg`(见[ecpg](#calibre_link-62)) 增加命令行选项`-t`, 或者是通过`EXEC SQL SET AUTOCOMMIT TO ON`语句。 在自动提交模式里,每条命令都是自动提交的, 除非它们包围在一个明确的事务块里。 这个模式可以用`EXEC SQL SET AUTOCOMMIT TO OFF`明确地关闭。 有以下事务管理命令可用: `EXEC SQL COMMIT` 提交正在进行的事务。 `EXEC SQL ROLLBACK` 回滚正在进行的事务。 `EXEC SQL SET AUTOCOMMIT TO ON` 启动自动提交模式。 `SET AUTOCOMMIT TO OFF` 禁用自动提交模式。这是缺省的。 ## 33.3.4\. 预备语句 当编译时间不知道该值已被传递给SQL语句,或者同一语句将使用多次, 那么预备语句是有帮助的。 使用命令`PREPARE`准备语句。对于不知道的值, 使用占位符"`?`": ``` EXEC SQL PREPARE stmt1 FROM "SELECT oid, datname FROM pg_database WHERE oid = ?"; ``` 如果一个语句返回单行,应用程序可以在`PREPARE` 执行语句之后调用`EXECUTE`, 使用`USING`子句为占位符提供实际值: ``` EXEC SQL EXECUTE stmt1 INTO :dboid, :dbname USING 1; ``` 如果一个语句返回多行,应用程序可以使用基于预备语句声明的游标。 为了结合输入参数,必须使用`USING`子句打开游标: ``` EXEC SQL PREPARE stmt1 FROM "SELECT oid,datname FROM pg_database WHERE oid > ?"; EXEC SQL DECLARE foo_bar CURSOR FOR stmt1; /* 当结果集达到最后时,打破while循环 */ EXEC SQL WHENEVER NOT FOUND DO BREAK; EXEC SQL OPEN foo_bar USING 100; ... while (1) { EXEC SQL FETCH NEXT FROM foo_bar INTO :dboid, :dbname; ... } EXEC SQL CLOSE foo_bar; ``` 当你不再需要预备语句的时候,你应该重新分配它: ``` EXEC SQL DEALLOCATE PREPARE _name_; ``` 为获得关于`PREPARE`的更多详情, 请参阅[PREPARE](#calibre_link-1996)。同时参阅[Section 33.5](#calibre_link-1997) 获得关于占位符和输入参数的更多详情。