↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3
历史版本PostgreSQL 8.0 已于 2010 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

29.6. 使用主变量 #

在第 29.4 节中,你已经看到如何从嵌入式 SQL 程序中执行 SQL 语句。其中一些语句只使用固定值,既无法把用户提供的值插入语句中,也无法让程序处理查询返回的值。这类语句在实际应用中并不真正有用。本节将详细解释如何使用一种称为主变量的简单机制,在 C 程序与嵌入式 SQL 语句之间传递数据。

29.6.1. 概述

在嵌入式 SQL 中,在 C 程序和 SQL 语句之间传递数据特别简单。我们不必让程序把数据拼接进语句中去,那样会带来诸如正确为值加引号等各种复杂问题;只需在 SQL 语句中写出 C 变量的名称,并在前面加上一个冒号即可。例如:

EXEC SQL INSERT INTO sometable VALUES (:v1, 'foo', :v2);

该语句引用了两个名为v1和v2的 C 变量,同时还使用了一个普通的 SQL 字符串常量,以说明你并不局限于只使用某一种数据。

这种在 SQL 语句中插入 C 变量的方式可以用在 SQL 语句中每一个应该出现值表达式的地方。在 SQL 环境中,我们把对 C 变量的引用称为主变量。

29.6.2. 声明节

要把数据从程序传给数据库(例如作为查询参数),或者把数据从数据库传回程序,用来承载这些数据的 C 变量必须声明在经过特殊标记的区段中,这样嵌入式 SQL 预处理器才能识别它们。

这个区段始于:

EXEC SQL BEGIN DECLARE SECTION;

并结束于:

EXEC SQL END DECLARE SECTION;

在这两行之间,必须是正常的 C 变量声明,例如:

int   x;
char  foo[16], bar[16];

一个程序中可以根据需要放置任意多个声明节。

这些声明也会作为普通 C 变量声明写入输出文件,因此无需再次声明它们。不准备在 SQL 命令中使用的变量可以照常在这些特殊声明节之外声明。

结构体或联合的定义也必须写在DECLARE声明节中。否则预处理器无法处理这些类型,因为它不知道它们的定义。

特殊类型VARCHAR会被转换成每个变量的一个命名的struct。像这样的声明:

VARCHAR var[180];

会被转换为:

struct varchar_var { int len; char arr[180]; } var;

这个结构适合与varchar类型的 SQL 数据交互。

29.6.3. SELECT INTO and FETCH INTO

现在你应该能够把程序产生的数据传递到一个 SQL 命令中了。但是怎么检索一个查询的结果呢?为此,嵌入式 SQL 提供了常规命令SELECT和FETCH的特殊变体。这些命令有一个特殊的INTO子句,它指定被检索到的值要被存储在哪些主变量中。

这里是一个例子:

/*
 * 假定有下列表:
 * 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;

那么INTO子句出现在选择列表和FROM子句之间。选择列表中的元素数量必须和INTO后面列表(也被称为目标列表)的元素数量相等。

这里有一个使用命令FETCH的例子:

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 (...);

这里INTO子句出现在所有正常子句的后面。

29.6.4. 指示符

上面这两种方法每次都只能检索单行数据。如果需要处理可能包含多于一行的结果集,就需要使用游标,如第二个示例所示。

上面的示例没有处理空值。实际上,如果读取示例从数据库取得空值,就会抛出错误。要向数据库传入空值或从数据库取得空值,需要在每个包含数据的主变量后,再指定第二个主变量。第二个主变量称为指示符,其中包含一个标志,表示该数据是否为空值;如果为空值,就会忽略实际主变量的值。下面的示例能正确处理空值的读取:

EXEC SQL BEGIN DECLARE SECTION;
VARCHAR val;
int val_ind;
EXEC SQL END DECLARE SECTION:

 ...

EXEC SQL SELECT b INTO :val :val_ind FROM test1;

指示符变量 val_ind 在数据非空时为零,在数据为空值时为负数。

指示符有另一种功能:如果指示符值为正,它表示值不为空,但是当它被存储在主变量中时已被截断。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。