运行SQL命令

PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 33. ECPG - 在C中嵌入SQL | 下一页

# 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` 语句。为了处理多行结果集，应用程序必须使用游标； 参阅第 33.3.2 节。（特殊情况下，应用程序可以一次读取多行到数组宿主变量中； 参阅第 33.4.4.3.1 节。）

单行select:

    EXEC SQL SELECT foo INTO :FooBar FROM table1 WHERE ascii = 'doodad';

同时，可以使用`SHOW`命令检索配置参数：

    EXEC SQL SHOW search_path INTO :var;

形如`:`something`` 这样的记号是宿主变量，也就是说，他们指向C程序中的变量。 在第 33.4 节中有解释。

## 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，关于 `FETCH`命令的细节请参阅FETCH。

> 注意: ECPG `DECLARE`命令实际上不会造成语句被发送到PostgreSQL后端。 当执行`OPEN`命令时， 在后端(使用后端的`DECLARE`命令)打开游标。

## 33.3.3. 管理事务

在缺省模式下，语句只有在`EXEC SQL COMMIT` 发出的时候才提交， 嵌入的SQL接口也支持事务的自动提交（类似libpq的行为）， 方法是通过给`ecpg`（见ecpg） 增加命令行选项`-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。同时参阅第 33.5 节 获得关于占位符和输入参数的更多详情。

上一页 | 起始页 | 下一页
管理数据库连接 | 上一级 | 使用宿主变量