更新时间:2026-10-21 GMT+08:00
分享

执行带有结果集的语句

当需要动态执行返回结果集的查询语句(SELECT)时,根据查询结果是单行还是多行,采用不同的处理机制。

单行动态查询

如果确定动态查询仅返回单行数据,可以直接结合PREPARE与EXECUTE指令,并通过INTO子句将检索到的字段值存入宿主变量,同时利用USING子句绑定输入参数:

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;

/* 预编译动态SQL文本 */
EXEC SQL PREPARE mystmt FROM :stmt;

...

/* 执行动态查询:将结果存入INTO指定的宿主变量,并将37绑定给?占位符 */
EXEC SQL EXECUTE mystmt INTO :v1, :v2, :v3 USING 37;

多行动态查询

如果动态查询可能返回多行数据,则无法直接通过EXECUTE ... INTO获取结果,必须结合动态游标进行流式遍历提取。游标详情请参见使用游标,示例如下:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    EXEC SQL BEGIN DECLARE SECTION; 
    char dbaname[128]; 
    char datname[128]; 
    const char *stmt = "SELECT u.usename as dbaname, d.datname "      
                       " FROM pg_database d, gs_user u "     
                       " WHERE d.datdba = u.usesysid"; 
    EXEC SQL END DECLARE SECTION;  

    EXEC SQL CONNECT TO testdb AS con1 USER testuser;  

    /* 1.预编译动态SQL语句 */
    EXEC SQL PREPARE stmt1 FROM :stmt;  

    /* 2.基于预编译句柄声明动态游标 */
    EXEC SQL DECLARE cursor1 CURSOR FOR stmt1; 

    /* 3.打开游标以启动查询解析与执行 */
    EXEC SQL OPEN cursor1;  

    EXEC SQL WHENEVER NOT FOUND DO BREAK;  

    /* 4.逐行提取查询结果存入宿主变量 */
    while (1) 
    {     
        EXEC SQL FETCH cursor1 INTO :dbaname, :datname;
        printf("dbaname=%s, datname=%s\n", dbaname, datname); 
    }  

    /* 5.显式关闭游标并释放资源 */
    EXEC SQL CLOSE cursor1;  

    EXEC SQL COMMIT; 
    EXEC SQL DISCONNECT ALL;
    return 0;
}

相关文档