第三十五章 ECPG-C中的嵌入式SQL
本章介绍PostgreSQL的嵌入式SQL包。最初它是为了与C一起工作而编写的。它也能与C++配合,但是它还不识别所有的C++结构。35.1概念嵌入式SQL程序由编程语言(C)编写的代码混合特殊标记的SQL命令而成。35.2管理数据库连接本节介绍如何打开、关闭和转换数据库连接。35.2.1连接到数据库服务使用以下语句连接到数据库服务:EXEC SQL CONNECT TO target [AS c
本章介绍PostgreSQL的嵌入式SQL包。最初它是为了与C一起工作而编写的。它也能与C++配合,但是它还不识别所有的C++结构。
35.1 概念
嵌入式SQL程序由编程语言(C)编写的代码混合特殊标记的SQL命令而成。
35.2 管理数据库连接
本节介绍如何打开、关闭和转换数据库连接。
35.2.1 连接到数据库服务
使用以下语句连接到数据库服务:
EXEC SQL CONNECT TO target [AS connection-name] [USER user-name];
35.2.2 选择连接
嵌入式SQL程序中的SQL语句默认在当前连接中执行。如果应用程序需要管理多个连接,则有两种方式实现:
-
显式为每个SQL语句选择连接:EXEC SQL AT connection-name SELECT ...;
-
执行切换当前连接的语句:EXEC SQL SET CONNECTION connection-name;
35.2.3 关闭连接
EXEC SQL DISCONNECT [connection];
35.3 运行SQL命令
嵌入式SQL应用程序中可运行任意SQL命令。
35.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;
返回单行的SELECT语句也可直接使用EXEC SQL执行,如果返回多行, 需要使用游标(cursor)。
EXEC SQL SELECT foo INTO :FooBar FROM table1 WHERE ascii = 'doodad';
查看参数配置:
EXEC SQL SHOW search_path INTO :var;
35.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;
35.3.3 管理事务
默认,仅当执行EXEC SQL COMMIT时语句才会提交。嵌入式SQL接口也可支持事务的自动提交(使用-t参数或EXEC SQL SET AUTOCOMMIT TO ON)。
可使用以下事务管理命令:
-
EXEC SQL COMMIT
-
EXEC SQL ROLLBACK
-
EXEC SQL PREPARE TRANSACTION transaction_id
-
EXEC SQL COMMIT PREPARED transaction_id
-
EXEC SQL ROLLBACK PREPARED transaction_id
-
EXEC SQL SET AUTOCOMMIT TO ON
-
EXEC SQL SET AUTOCOMMIT TO OFF
35.3.4 预编译语句
当在编译时传递到SQL语句的值还未知,或相同语句执行多次时,那么预编译语句就很有用处。语句使用PREPARE命令进行预编译。使用?进行未知值占位:
EXEC SQL PREPARE stmt1 FROM "SELECT oid, datname FROM pg_database WHERE oid = ?";
35.4 使用主变量
本节介绍如何在C程序与嵌入式SQL语句间通过主变量(host variables)传递数据。在嵌入式SQL程序中,SQL语句为C程序代码的客(guest),C程序为主(host)。所以C程序的变量称为主变量。
另一种在PostgreSQL后台进程与ECPG应用程序间交互数据的方式为SQL描述符,参见第35.7节。
35.4.1 概览
在C程序和SQL语句间传递数据在嵌入式SQL中颇为简单。示例:
EXEC SQL INSERT INTO sometable VALUES (:v1, 'foo', :v2);
35.4.2 声明section
在传递数据的时候,需要为其声明一个特殊的标记区域(section),以便嵌入式SQL预处理器可以处理它。该区域以EXEC SQL BEGIN DECLARE SECTION;开始,以EXEC SQL END DECLARE SECTION;结束。在这之间,需要是标准的C变量声明,例如:
int x = 4;
char foo[16], bar[16];
也可用以下语法声明变量,这可以隐式创建一个声明区域:
EXEC SQL int i = 4;
35.4.3 检索查询结果
返回单行的使用SELECT,返回多行的使用FETCH。
示例:
/*
* 表DDL:
* CREATE TABLE test1 (a int, b varchar(50));
*/
EXEC SQL BEGIN DECLARE SECTION;
int v1;
VARCHAR v2;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL SELECT a, b INTO :v1, :v2 FROM test;
EXEC SQL BEGIN DECLARE SECTION;
int v1;
VARCHAR v2;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL DECLARE foo CURSOR FOR SELECT a, b FROM test;
...
do
{
...
EXEC SQL FETCH NEXT FROM foo INTO :v1, :v2;
...
} while (...);
35.4.4 类型匹配
数据类型需要在PostgreSQL数据类型和主语言变量类型(当前为C语言数据类型)之间转换。表35.1展示PostgreSQL数据类型与C数据类型的匹配:


35.4.5 处理非基础SQL数据类型
本节介绍如何在ECPG应用程序中处理非标准以及用户自定义的SQL级别的数据类型。
35.4.5.1 Array
ECPG不直接支持多维SQL级别的数组。如果使用查询分别访问数组的元素这就可避免在ECPG中使用数组。不过需要定义与元素数据类型匹配的主变量。
35.4.5.2 复合数据类型
ECPG不直接支持复合数据类型,但可提供与数组类似的折中解决方案。
35.4.5.3 用户定义的基础数据类型
ECPG不直接支持用户新定义的基础类型。但可以使用外部字符串表示以及主变量类型char[]或varchar[]。
35.4.6 指标
以上示例均无法处理null值。为处理null值,需要在每个主变量附加第二个变量:indicator(指标),其包含一个判断值是否为空的标记。
35.5 动态SQL
有时候,应用程序执行的SQL语句在执行时就可确定,但有的时候SQL语句确是在运行时或由外部提供。在这些情况下,无法直接将SQL语句嵌入到SQL源码中,但仍有解决方案。
35.5.1 执行没有结果集返回的语句
执行动态语句最简单的方式是执行EXECUTE IMMEDIATE。示例:
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "CREATE TABLE test1 (...);";
EXEC SQL END DECLARE SECTION;
EXEC SQL EXECUTE IMMEDIATE :stmt;
35.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;
35.5.3 执行有结果集的语句
执行返回单结果集的SQL语句,使用EXECUTE。使用INTO子句保留结果集。多行结果集,需要使用游标。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)