ecpg-dynamic.md 3.1 KB
Newer Older
李少辉-开发者's avatar
李少辉-开发者 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
## 36.5.动态SQL

[36.5.1. 执行没有结果集的语句](ecpg-dynamic.html#ECPG-DYNAMIC-WITHOUT-RESULT)

[36.5.2. 使用输入参数执行语句](ecpg-dynamic.html#ECPG-DYNAMIC-INPUT)

[36.5.3. 使用结果集执行语句](ecpg-dynamic.html#ECPG-DYNAMIC-WITH-RESULT)

在许多情况下,应用程序必须执行的特定SQL语句在编写应用程序时是已知的。然而,在某些情况下,SQL语句是在运行时编写的,或者由外部源提供。在这些情况下,您无法将SQL语句直接嵌入到C源代码中,但有一个工具允许您调用在字符串变量中提供的任意SQL语句。

### 36.5.1.执行没有结果集的语句

执行任意SQL语句的最简单方法是使用以下命令`立即执行`.例如:

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

EXEC SQL EXECUTE IMMEDIATE :stmt;
```

`立即执行`可用于不返回结果集的SQL语句(例如DDL、,`插入`,`使现代化`,`删去`).您不能执行检索数据的语句(例如。,`选择`)这边。下一节将介绍如何做到这一点。

### 36.5.2.使用输入参数执行语句

执行任意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';
```

当你不再需要准备好的声明时,你应该取消分配它:

```
EXEC SQL DEALLOCATE PREPARE name;
```

### 36.5.3.使用结果集执行语句

要使用单个结果行执行SQL语句,`处决`可以使用。要保存结果,请添加`进入`条款

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

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

`处决`命令可以有一个`进入`条款a`使用`子句,两者都可以,或者两者都不可以。

如果一个查询需要返回多个结果行,那么应该使用游标,如下例所示。(见[第36.3.2节](ecpg-commands.html#ECPG-CURSORS)有关光标的详细信息。)

```
EXEC SQL BEGIN DECLARE SECTION;
char dbaname[128];
char datname[128];
char *stmt = "SELECT u.usename as dbaname, d.datname "
             "  FROM pg_database d, pg_user u "
             "  WHERE d.datdba = u.usesysid";
EXEC SQL END DECLARE SECTION;

EXEC SQL CONNECT TO testdb AS con1 USER testuser;
EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;

EXEC SQL PREPARE stmt1 FROM :stmt;

EXEC SQL DECLARE cursor1 CURSOR FOR stmt1;
EXEC SQL OPEN cursor1;

EXEC SQL WHENEVER NOT FOUND DO BREAK;

while (1)
{
    EXEC SQL FETCH cursor1 INTO :dbaname,:datname;
    printf("dbaname=%s, datname=%s\n", dbaname, datname);
}

EXEC SQL CLOSE cursor1;

EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
```