返回首页

gbase数据、南大通用产品文档:GBase8cALTER SYNONYM

更新日期:2024年09月11日

功能描述

修改SYNONYM 对象的属性。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
750
注意事项

目前仅支持修改SYNONYM 对象的属主。

只有系统管理员有权限修改SYNONYM 对象的属主信息。

新属主必须具有SYNONYM 对象所在模式的CREATE 权限。
语法格式
ALTER SYNONYM synonym_name
OWNER TO new_owner;
参数描述

synonym
待修改的同义词名字,可以带模式名。
取值范围:字符串,需要符合标识符的命名规范。

new_owner
同义词对象的新所有者。
取值范围:字符串,有效的用户名。
示例
--创建同义词t1。
gbase=# CREATE OR REPLACE SYNONYM t1 FOR ot.t1;
--创建新用户u1。
gbase=#CREATE USER u1 PASSWORD 'user@111';
--修改同义词t1 的owner 为u1。
gbase=#ALTER SYNONYM t1 OWNER TO u1;
--删除同义词t1。
gbase=#DROP SYNONYM t1;

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
751
--删除用户u1。
gbase=#DROP USER u1;
相关命令
CREATE SYNONYM,DROP SYNONYM

使用 UPDATE 语句来更改表或视图中一个或多个现有的行的一个或多个列中的
值。
语法
Target

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1121

WHERE 选项

元素
描述
限制
语法
alias
您在此为本地表或远
程表声明的临时的名

如果 SET 是 alias 的标识
符,则 AS 关键字必须在
alias 之前
标识符
condition 被更新的行必须满足
的逻辑标准
不可为 UDR 或相关联的子
查询
条件
cursor
要更新其当前行的游
标的名称
不可为主变量。您不可更新
包括合计的行
标识符
synonym、
table、
view
包含要被更新的行的
同义词、表或视图
synonym 和表或它指向的视
图必须存在
数据库对
象名
用法
使用 UPDATE 语句来更新任何下列类型的数据库对象或程序对象:

表中的一行:单个行、行的组或表中的所有行

集合数据类型的列中的元素

在命名的或未命名的 ROW 数据类型的列中,一个字段或所有字段。
随同 GBase 8s ,您还可使用此语句来更改在 GBase 8s ESQL/C 或 SPL 集合变
量或 ROW 变量中一个或多个元素的值。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1122
要获取关于如何更新集合变量的元素的信息,请参阅 集合派生表。在此
UPDATE 语句的描述中接下来的部分描述如何更新表中的行。
您必须或拥有该表,或对该表有 Update 权限。请参阅 GRANT 语句。要更新视
图中的数据,您必须有 Update 权限,且该视图必须满足 通过视图更新行 中说
明的要求。
UPDATE 语句的目标不可为 CREATE EXTERNAL TABLE 语句定义了的表对
象。
游标(如 DECLARE 语句的 SELECT ... FOR UPDATE 部分中定义的那样)可仅
包含列名称。如果您省略 WHERE 子句,则更新目标表的所有行。
如果您正在使用有效的检查,且检查模式设置为 IMMEDIATE,则在每一
UPDATE 语句的结尾处检查所有启用的约束。如果检查模式设置为
DEFERRED,则直到提交事务才检查所有启用的约束。
在 DB-Access 中,如果您省略 WHERE 子句,且处于交互的模式中,则 DB-
Access 不运行 UPDATE 语句,直到您确认您想要更改所有行为止。然而,如果
该语句在命令文件中,且您在在命令行运行,则立即执行该语句。
示例
下列示例创建并更新视图。
CREATE VIEW cust_view AS SELECT * FROM customer;
UPDATE cust_view SET customer_num=10001 WHERE customer_num=101;
使用 ONLY 关键字
如果您使用 UPDATE 语句来更新超级表的行,则还可更新来自它的子表的行。
要仅更新来自超级表的行,请在表名称之前使用 ONLY 关键字,如此示例所
示:
UPDATE ONLY(am_studies_super)
WHERE advisor = "johnson"
SET advisor = "camarillo";
注: 如果您在超级表上使用不带有 ONLY 关键字且不带有 WHERE 子句的
UPDATE 语句,则更新超级表的所有行和它的子表。如果您计划使用 WHERE

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1123
CURRENT OF 子句来更新游标的活动集的当前行,则您不可使用 ONLY 关键
字。
通过视图更新行
如果您在视图上有 Update 权限,则您可通过单表视图更新数据(请参阅
GRANT 语句)。对于可更新的视图,定义该视图的查询必须不包含任何下列
项:

projection 列表中聚集值的列

projection 列表中使用 UNIQUE 或 DISTINCT 关键字的列

GROUP BY 子句

UNION 运算符
此外,如果在有列的派生值的表上构建视图,则不可通过该视图更新那列。然
而,可更新该视图中的其他列。在可更新的视图中,您可通过将值插入到该视图
内来更新基础表中的值。
CREATE VIEW cust_view AS SELECT * FROM customer;
UPDATE cust_view SET customer_num=10001 WHERE customer_cum=101;
下列语句定义包括 customer 表中所有行的视图,并将列值为 101 的任何行中的
customer_num 值更改为 10001:
CREATE VIEW cust_view AS SELECT * FROM customer;
UPDATE cust_view SET customer_num=10001 WHERE customer_num=101;
当更新值不适合定义了该视图的 SELECT 语句时,您可使用数据完整性约束来防
止用户更新基础表中的值。要获取更多信息,请参阅 WITH CHECK OPTION 关
键字。
由于即使视图的基本表有唯一的行,在视图仍可发生重复的行,因此当通过视图
更新表时请小心。例如,如果在 items 表上定义视图,且仅包含 order_num 和
total_price 列,且如果来自同一订单的两项有相同的总价,则该视图包含重复
的行。在此情况下,如果您更新两个重复的 total_price 值中的一个,则您无法
知道更新哪个项价格。
重要: 如果您正在使用带有检查点的视图,则您不可更新远程表中的行。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1124
以 UPDATE 语句直接修改视图中的数据值的替代方法,是在该视图上创建
INSTEAD OF 触发器。要获取更多信息,请参阅 视图上的 INSTEAD OF 触发
器。
在没有事务的数据库中更新行
如果您正在在没有事务的数据库中更新行,则您必须采取显式的活动来恢复更新
了的行。例如,如果在更新某些行之后 UPDATE 语句失败,则成功地更新了的
行保留在表中。您不可自动地从失败的更新中恢复。
在带有事务的数据库中更新行
如果您正在带有事务的数据库中更新行,且您正在使用事务,则您将可使用
ROLLBACK WORK 语句撤销更新。如果在更新之前您未执行 BEGIN WORK 语
句,且更新失败,则数据库服务器自动地回滚自从更新操作开始以来对该表进行
的任何数据库修改。
CREATE TEMP TABLE 语句可包括 WITH NO LOG 选项来创建不支持事务日志
记录的临时表。这些表不进行日志记录且不可恢复。
请不要在事务内使用 RAW 表。您以 CREATE RAW TABLE 语句创建的表不进
行日志记录。因此,RAW 表是不可恢复的,即使数据库使用日志恢复。RAW 表
通常用作初始加载和验证数据。在您已加载了数据之后,请使用 ALTER TABLE
语句来将该表更改为类型 STANDARD,并在您在事务中使用该表之前执行 0 级
备份。要获取更多关于 RAW 表的信息,请参考 GBase 8s 管理员指南。
在符合 ANSI 的数据库中,事务是隐式的,且所有数据库修改都发生在事务内。
在此情况下,如果 UPDATE 语句失败,您可使用 ROLLBACK WORK 来撤销更
新。
如果您在显式的事务内,且更新失败,则数据库服务器自动地撤销该更新的影
响。
锁定注意事项
当带着更新的意图选择行时,该更新进程需要 update 锁。update 锁允许其他进
程读或共享将要被更新的行,但它们不允许那些进程更新或删除它。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1125
就在更新发生之前,更新进程将共享锁提升为排他锁。排他锁防止其他进程读取
或修改行的内容,直到释放该锁为止。
更新进程可从另一进程在行上或在有共享锁的页上获得 update 锁,但您不可将
update 锁从共享的提升到排他的(且不可发生更新),直到其他进程释放它的锁
为止。
如果单个更新影响的行的数目很大,则您可超过在同时发生的锁的最大数目上设
置的限制。如果发生此情况,则您可减少每 UPDATE 语句的事务数,或您可在
执行该语句之前锁定页或整个表。
为目标表声明别名
您可为目标表声明别名。该别名可引用本地或远程表、视图或同义词的完全符合
条件的数据库对象。
别名是不注册在数据库的系统目录中的临时名称,仅在 UPDATE 语句正在运行
时保持。
如果您声明作为别名的名称还是 UPDATE 语句的关键字,则您必须使用 AS 关键
字来阐明语法:
UPDATE stock AS set
SET unit_price = unit_price * 0.94;
下列 UPDATE 语句引用在目标子句中和在两个子查询中表的符合要求的名称:
UPDATE nmosdb@wnmserver1:test
SET name=(SELECT name FROM test
WHERE test.id = nmosdb@wnmserver1:test.id)
WHERE EXISTS(
SELECT 1 FROM test WHERE test.id = nmosdb@wnmserver1:test.id
);
下一 UPDATE 语句在逻辑上等同于前一示例,但为符合条件的表名称声明 r_t
别名:
UPDATE nmosdb@wnmserver1:test r_t
SET name=(SELECT name FROM test
WHERE test.id = r_t.id)
WHERE EXISTS(
SELECT 1 FROM test WHERE test.id = r_t.id

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1126
);
声明表别名会简化上述第二个示例的标记。
SET 子句
使用 SET 子句来标识要更新的列并将值指定给每一列。
SET 子句支持下列语法格式:

单列格式,它将每一列与单个表达式配对

多列格式,它将多列的列表与通过一个或多个表达式返回的值相关联
SET 子句

单列格式
使用单列格式来将一列与单个表达式配对。
单列格式

元素
描述
限制
语法
column
要被更新的列
不可为序列数据类型
标识符
collection_var
主变量或程序变量
必须声明作为集合数据
类型
特定于语

expression
为 column 返回一值 不可包含聚集函数
表达式

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1127
元素
描述
限制
语法
singleton
_select
正好返回一行的子查

返回的子查询值必须与
column 列表一一对应
SELECT 语

您可使用此语法来更新有 ROW 数据类型的列。
您可包括任意数量的 "single column = single expression" 词语。expression 可为返
回单个行的 SQL 子查询(括在圆括号之间),假如对应的 column 为可从子查
询返回的行存储该值(或值的集合)的数据类型。
要在 SET 子句中指定 ROW 类型列的值,请参阅 更新 ROW 类型列。下列示例说
明 SET 子句的单列格式。
UPDATE customer
SET address1 = '1111 Alder Court', city = 'Palo Alto',
zipcode = '94301' WHERE customer_num = 103;

UPDATE stock
SET unit_price = unit_price * 1.07;
使用子查询来更新单列
您可以子查询返回的值更新在 SET 子句中指定的列。
UPDATE orders
SET ship_charge =
(SELECT SUM(total_price) * .07 FROM items
WHERE orders.order_num = items.order_num)
WHERE orders.order_num = 1001;
如果您正在更新表层级中的超级表,则 SET 子句不可包括引用子表的子查询。
如果您正在更新表层级中的子表,则 SET 子句中的子查询可引用超级表,如果
它仅引用超级表的话。也就是说,子查询必须使用 SELECT … FROM ONLY
(supertable) 语法。
将列更新为 NULL
当您使用 UPDATE 语句时,请使用 NULL 关键字来修改列值。例如,对于其先
前的地址需要两个地址行但现在仅需要一个的客户,您可以使用下列条目:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1128
UPDATE customer
SET address1 = '123 New Street',
SET address2 = null,
city = 'Palo Alto',
zipcode = '94303'
WHERE customer_num = 134;
两次更新同一列
您可在 SET 子句中指定同一列一次以上。如果您这么做,则将该列设置为您为
该列指定的最后的值。在下一示例中,fname 列在 SET 子句中出现两次。对于
客户编号为 101 的行,用户先将 fname 设置为 gary 然后又设置为 harry。在
该 UPDATE 语句执行之后,fname 的值为 harry。
UPDATE customer
SET fname = "gary", fname = "harry"
WHERE customer_num = 101;
多列格式
使用 SET 子句的多列格式来罗列多个列并将它们设置等于相应的表达式。
多列格式

元素
描述
限制
语法
column
要被更新的列
的名称
不可为序列类型或 ROW 类
型。column 名称的数目必须
等于返回到 = 号右边的值的
数目。
标识符
expression
为 column 返
回值的表达式
不可包括聚集函数
表达式

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1129
元素
描述
限制
语法
singleton_select
正好返回一行
的子查询
子查询返回的值必须对应于
column 列表中的列
SELECT
语句
SPL function
返回一个或多
个值的 SPL
例程
返回的值必须与 column 列表
中的列一一对应
标识符
SET 子句的多列格式为罗列您想要更新的列的集合提供下列选项:

显式地罗列每一列,在列之间放置逗号,将列的集合括在圆括号之间。

通过使用星号(*)隐式地罗列表中的所有列。
您必须显式地罗列每一表达式,在表达式之间放置逗号(,)分隔符,并将表达式
的集合括在圆括号之间。列的数目必须等于表达式列表所返回的值的数目,除非
该表达式列表包括一 SQL 子查询。
下列示例展示 SET 子句的多列格式:
UPDATE customer
SET (fname, lname) = ('John', 'Doe') WHERE customer_num = 101;

UPDATE manufact
SET * = ('HNT', 'Hunter') WHERE manu_code = 'ANZ';
使用子查询来更新多列值
该表达式列表可包括一个或多个子查询。每一必须返回包含一个或多个值的单个
行。SET 子句显式地或隐式地指定的列的数目必须等于在多列 SET 子句中等号
(=)之后的表达式(或表达式列表)所返回的值的数目。
必须将子查询括在圆括号之间。这些圆括号嵌套在紧跟在等号(=)之后的圆括号
之内。如果表达式列表包括多个子查询,则必须将每一子查询括在圆括号之间,
以逗号(,)分隔连续的子查询:
UPDATE ... SET ... = ((subqueryA),(subqueryB), ... (subqueryN))
下列示例展示 SET 子句中子查询的使用:
UPDATE items
SET (stock_num, manu_code, quantity) =

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1130
( (SELECT stock_num, manu_code FROM stock
WHERE description = 'baseball'), 2)
WHERE item_num = 1 AND order_num = 1001;

UPDATE table1
SET (col1, col2, col3) =
((SELECT MIN (ship_charge), MAX (ship_charge) FROM orders),
'07/01/2007')
WHERE col4 = 1001;
如果您正在更新表层级中的超级表,则 SET 子句不可包括引用它的子表之一的
子查询。如果您正在更新表层级中的子表,则 SET 子句中的子查询可引用超级
表,如果它仅引用超级表的话。也就是说,子查询必须使用 SELECT… FROM
ONLY (supertable) 语法。
更新 ROW 类型列
使用 SET 子句来更新命名的或未命名的 ROW 类型列。例如,假设您定义下列
命名的 ROW 类型和包含命名的和未命名的 ROW 类型的列的表:
CREATE ROW TYPE address_t
(
street CHAR(20), city CHAR(15), state CHAR(2)
);
CREATE TABLE empinfo
(
emp_id INT
name ROW ( fname CHAR(20), lname CHAR(20)),
address address_t
);
要更新未命名的 ROW 类型,请在圆括号括起的字段值的列表之前指定 ROW 构
造函数。
下列语句更新 empinfo 表的 name 列(未命名的 ROW 类型):
UPDATE empinfo SET name = ROW('John','Williams') WHERE emp_id =455;
要更新命名的 ROW 类型,请在字段值的列表(在圆括号中)之前指定 ROW 构
造函数,并使用强制转型(::)运算符来将 ROW 值强制转型为命名的 ROW 类
型。下列语句更新 empinfo 表的 address 列(命名的 ROW 类型):

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1131
UPDATE empinfo
SET address = ROW('103 Baker St','Tracy','CA')::address_t
WHERE emp_id = 3568;
要获取更多关于 ROW 构造函数的语法,请参阅 构造函数表达式。另请参阅
Literal Row。
ROW 列 SET 子句仅可支持字段的文字值。要使用 ESQL/C 变量来指定字段
值,您必须将 ROW 数据选择到 row 变量内,使用单独的字段值的主变量,然
后以 row 变量更新 ROW 列。要获取更多信息,请参阅 更新 Row 变量
(ESQL/C)。
您可使用 GBase 8s ESQL/C 主变量来插入非文字值作为:

整个 row 类型插入列内
使用 row 变量作为 SET 子句中的变量名称来一次更新 ROW 列中的所
有字段。

ROW 类型的单独字段
要将非文字值插入 ROW 类型列内,您可首先更新 row 变量中的元素,
然后指定在 UPDATE 语句的 SET 子句中的 collection 变量。
当您使用 SET 子句中的 row 变量时,row 变量必须包含每一字段值的值。要获
取关于如何将值插入到 row 变量内的信息,请参阅 更新 Row 变量
(ESQL/C)。
您可使用 UPDATE 语句来只修改行中的某些字段:

以字段 projection 指定其值保持不变的所有字段的字段名称
例如,下列 UPDATE 语句仅更改 empinfo 表的 address 列的 street 和
city 字段:
UPDATE empinfo
SET address = ROW('23 Elm St', 'Sacramento', address.state)
WHERE emp_id = 433;
address.state 字段保持不变。

将该行选择到 ESQL/C row 变量内并更新期望的字段。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1132
要获取更多信息,请参阅 更新 Row 变量(ESQL/C)。
更新集合列
您可使用 SET 子句来更新集合列中的值。要获取更多信息,请参阅 集合构造函
数。
集合变量可更新集合类型列。以集合变量,您可插入一个或多个集合的单独元
素。要获取更多信息,请参阅 集合派生表。
例如,假设您定义 tab1 表如下:
CREATE TABLE tab1
(
int1 INTEGER,
list1 LIST(ROW(a INTEGER, b CHAR(5)) NOT NULL),
dec1 DECIMAL(5,2)
);
下列 UPDATE 语句更新 tab1 中的一行:
UPDATE tab1
SET list1 = LIST{ROW(2, 'zyxwv'),
ROW(POW(2,6), '=64'),
ROW(ROUND(ROOT(146)), '=12')},
WHERE int1 = 10;
在此示例中的集合列 list1 有三个元素。每一元素是带有 INTEGER 字段和
CHAR(5) 字段的未命名的 ROW 类型。第一个元素包括两个文字值:一个整数
(2 )和一个引号括起的字符串('zyxwv')。
第二个和第三个元素还使引用字符串来表明第二个字段的值。然而,它们以表达
式,而不是以文字值,来指定第一个字段的值。
更新 Opaque 类型列中的值
当更新某些 opaque 数据类型时,它们需要特殊的处理。例如,如果 opaque 数据
类型包含空间的数据或多重表示的数据,则它可能提供如何存储该数据的选择:
在内部的结构之内,还是在智能大对象之中(对于大对象)。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1133
通过调用名为 assign( ) 的用户定义的支持函数来完成此处理。当您在其行包含这
些 opaque 类型之一的表上执行 UPDATE 时,数据库服务器自动地调用该类型
的 assign( ) 函数。此函数可作出如何存储该数据的决定。要获取更多关于
assign( ) 支持函数的信息,请参阅 GBase 8s 用户定义的例程和数据类型开发者指
南 。
分布式 UPDATE 操作中的数据类型
访问另一 GBase 8s 实例的数据库的 UPDATE 语句(或任何其他 SQL 数据操纵
语言语句)仅可引用下列数据类型:

内建的非 opaque 的数据类型

BOOLEAN

LVARCHAR

非 opaque 的内建的数据类型的 DISTINCT

BOOLEAN 的 DISTINCT

LVARCHAR 的 DISTINCT

出现在此列表中的任何 DISTINCT 数据类型的 DISTINCT。
跨服务器分布式 UPDATE 操作可支持这些 DISTINCT 类型,仅当将该
DISTINCT 类型显式地强制转型为内建的类型,且所有的 DISTINCT 类型、 它
们的数据类型层级以及它们的强制转型都正好以相同的方式定义在每一参与的服
务器中。 要获取关于在跨服务器 DML 操作中 GBase 8s 支持的数据类型的信
息,请参阅 跨服务器事务中的数据类型。
然而,访问本地 GBase 8s 实例的其他数据库的跨数据库分布式 UPDATE 操作可
访问在前面的列表中的跨服务器数据类型,还有下列数据类型:

大多数内建的 opaque 数据类型,如 跨数据库事务中的数据类型 中罗列
的那样

在前面的行中引用的内建的类型的 DISTINCT

在前面的两行中的一行中罗列的任何数据类型的 DISTINCT

显式地强制转型到内建的数据类型的 opaque 用户定义的数据类型
(UDT)。
跨数据库 UPDATE 操作可支持这些 DISTINCT 类型和 opaque UDT,仅当将所
有 opaque UDT 和 DISTINCT 类型强制转型到内建的类型,且所有的 opaque

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1134
UDT、DISTINCT 类型、数据类型层级和强制转型都正好以同样的方式定义在每
一参与的数据库中。
分布式 UPDATE 事务不可访问另一 GBase 8s 实例的数据库,除非两个服务器都
在它们的 DBSERVERNAME 或 DBSERVERALIASES 配置参数中以及在
sqlhosts 文件或 SQLHOSTS 注册子键中定义 TCP/IP 或 IPCSTR 连接。两参与
的服务器都要支持相同的连接类型(或 TCP/IP 或 IPCSTR),该要求也适用于
GBase 8s 实例之间的任何通信,即使双方位于同一台计算机上。
UPDATE 的 WHERE 子句
WHERE 子句让您指定搜索标准来限制要被更新的行。如果您省略 WHERE 子
句,则更新表中的每行。要获取更多信息,请参阅 SELECT 的 WHERE 子句。
当更新符合 ANSI 的数据库时的 SQLSTATE 值
如果您在符合 ANSI 的数据库中以 UPDATE 语句更新表,其中包含 WHERE
子句且未找到行,则数据库服务器发出警告。
您可以下列方式之一检测此警告条件:

GET DIAGNOSTICS 语句将 RETURNED_SQLSTATE 字段设置为值
02000。 在 SQL API 应用中,SQLSTATE 变量包含与此相同的值。

在 SQL API 应用中,sqlca.sqlcode 和 SQLCODE 变量包含值 100。
数据库服务器还将 SQLSTATE 和 SQLCODE 设置为这些值,如果 UPDATE ...
WHERE 语句是多语句 PREPARE 的一部分且数据库服务器不返回行的话。
当更新非 ANSI 数据库时的 SQLSTATE 的值
在不符合 ANSI 的数据库中,当数据库服务器发现没有与 UPDATE 语句的
WHERE 子句相匹配的行时,它不返回警告。SQLSTATE 代码为 00000 且
SQLCODE 代码为零(0)。然而,如果 UPDATE ... WHERE 语句是多语句
PREPARE 的一部分,且未返回行,则数据库服务器发出警告,并设置
SQLSTATE 为 02000,设置 SQLCODE 为 100。
GBase 8s 的客户端-服服务器通信协议,诸如 SQLI 和 DRDA®,支持
SQLSTATE 代码值。要了解这些代码的列表,以及要了解关于如何获得该消息
文本的信息,请参阅 使用 SQLSTATE 错误状态代码。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1135
UPDATE 的 WHERE 子句中的子查询
UPDATE 语句的 WHERE 子句中的子查询的 FROM 子句可指定与 UPDATE
语句的 Table Options 子句指定的同一表或视图作为数据源。仅当下列条件都为真
时,才支持带有引用同一表对象的子查询的 UPDATE 操作:

该子查询或者返回单个行,或者有不相关的列引用。

该子查询在 UPDATE 语句 WHERE 子句中,以 Subquery 语法使用
Condition。

在该子查询中没有 SPL 例程可引用 UPDATE 正在修改的同一表。
除非满足所有这些条件,否则包括引用 UPDATE 语句修改的同一表或视图的子
查询的 UPDATE 语句返回错误 -360。
下列示例通过将更新 unit_price 值减去价格子集的 5% 来更新 stock 表。
WHERE 子句通过将 IN 运算符应用于由子查询返回的行来指定减去哪个价格,仅
选择 unit_price 值大于 50 的 stock 表的行:
UPDATE stock SET unit_price = unit_price * 0.95
WHERE unit_price IN
(SELECT unit_price FROM stock WHERE unit_price > 50);
此子查询仅包括不相关的列引用,因为它的唯一的引用的列是在它的 FROM 子
句指定的表中。以上罗列的要求生效,因为该子查询的数据源与外部的 UPDATE
语句的 Table Options 子句指定的是相同的 stock 表。
前面的示例与发出两个单独的 DML 语句产生相同的结果:

SELECT 语句,从 stock 表返回临时表,tmp1 包含的行与子查询返回
的行相同。

UPDATE 语句,发出临时表的子查询作为在它的 WHERE 子句中的断言
来修改其 unit_price 与临时表中的执行匹配的 stock 表的每一行:
SELECT unit_price FROM stock WHERE unit_price > 50 INTO TEMP tmp1;
UPDATE stock SET unit_price = unit_price * 0.95
WHERE unit_price IN ( SELECT * FROM tmp1 );
这里是一个在它的 WHERE 子句中包括多个不相关的子查询的更复杂的
UPDATE 语句的示例:
UPDATE t1 SET a = a + 10
WHERE a > ALL (SELECT a FROM t1 WHERE a > 1) AND

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1136
a > ANY (SELECT a FROM t1 WHERE a > 10) AND
EXISTS (SELECT a FROM t1 WHERE a > 5);;
如果在表上定义启用的 Select 触发器,该表是修改同一表的 UPDATE 语句的
WHERE 子句中的子查询的数据源,则在该 UPDATE 语句之内执行那个子查询
不激活该 Select 触发器。请考虑下列程序片断:
CREATE TRIGGER selt11 SELECT ON t1 BEFORE
(UPDATE d1
SET (c1, c2, c3, c4, c5) =
(c1 + 1, c2 + 1, c3 + 1, c4 + 1, c5 + 1));

UPDATE t2 SET c1 = c1 +1
WHERE c1 IN
(SELECT t1.c1 from t1 WHERE t1.c1 > 10 );
在上述示例中,不作为 t2 上 UPDATE 操作的一部分激活表触发器 selt11。
UPDATE 语句的 WHERE 子句中的子查询可包括 UNION 或 UNION ALL 运算
符,如下例所示。
UPDATE t1 SET a = a + 10 WHERE a in (SELECT a FROM t1 WHERE a > 1
UNION SELECT a FROM t1, t2 WHERE a < b);
如果外部的 UPDATE 语句修改的表是表层级之内的类型表,则 GBase 8s 支持使
用 UPDATE 的 WHERE 子句中有效子查询的所有下列操作:

UPDATE 在目标父表上以子查询(SELECT from parent table)

UPDATE 在目标父表上以子查询(SELECT from child table)

UPDATE 在目标孩子表上以子查询(SELECT from parent table)

UPDATE 在目标孩子表上以子查询(SELECT from child table)。
下列程序片断说明以类型表上的子查询的 UPDATE 操作:
CREATE ROW TYPE r1 (c1 INT, c2 INT);
CREATE ROW TYPE r2 UNDER r1;
CREATE TABLE t1 OF TYPE r1; -- parent table
CREATE TABLE t2 OF TYPE r2 UNDER t1; -- child table

UPDATE t1 SET c1 = c1 + 1 WHERE c1 IN
( SELECT t1.c1 FROM t1 WHERE t1.c1 > 10);


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1137
UPDATE t1 SET c1 = c1 + 1 WHERE c1 IN
( SELECT t2.c1 FROM t2 WHERE t2.c1 > 10);

UPDATE t2 SET c1 = c1 + 1 WHERE c1 IN
( SELECT t2.c1 FROM t2 WHERE t2.c1 > 10);

UPDATE t2 SET c1 = c1 + 1 WHERE c1 IN
( SELECT t1.c1 FROM t1 WHERE t1.c1 > 10);
要获取更多关于如何使用返回多行作为 UPDATE 语句的 WHERE 子句中的断言
的信息,请参阅 带有子查询的条件 主题。
使用WHERE CURRENT OF 子句(ESQL/C、SPL)
使用 WHERE CURRENT OF 子句来更新 FOR UPDATE 声明了的游标的当前
行,或更新 Collection 游标的当前元素。
在此,不可指定游标名称做为主变量。
当前行是最近获取的行。由于 UPDATE 语句不会将游标前进到下一行,因此通
过此操作不更改在游标的活动集合内当前行的位置。
对于 GBase 8s 的表层级,您不可使用此子句,如果您正在仅从表层级中一个表
选择的话。也就是说,如果您使用 ONLY 关键字,则您不可使用此选项。
在 ESQL/C 例程中,要包括 WHERE CURRENT OF 关键字,您必须提前已经使
用了 DECLARE 语句来定义带有 FOR UPDATE 选项的游标。如果创建了该游标
的 DECLARE 语句指定了 FOR UPDATE 中的一个或多个列,则限制您仅可更新
随后的 UPDATE ... WHERE CURRENT OF 语句中的那些行。在 DECLARE 语
句的 FOR UPDATE 子句中指定列的优势在于速度。如果在 DECLARE 语句中指
定列,数据库服务器通常可更快地执行更新。
在 SPL 例程中,您可在 UPDATE 语句中的 WHERE CURRENT OF 关键字之后
指定游标,仅当您在 SPL 的 FOREACH 语句中声明了 cursor_id。您不可在
SPL 例程中使用 DECLARE 语句来声明动态游标的名称,以及将那个游标与
PREPARE 语句已在同一 SPL 例程中声明了的准备好的对象的语句标识符相关
联。
说明: Update 游标可执行以 UPDATE 语句不可能执行的更新。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1138
下列 GBase 8s ESQL/C 示例说明 WHERE 子句的 CURRENT OF 形式。在此示例
中,在收到 10% 折扣的客户的范围内(假设将新列 discount 添加到 customer
表)执行更新。在 WHILE 循环的外部准备 UPDATE 语句来确保仅执行一次解析。
char answer [1] = 'y';
EXEC SQL BEGIN DECLARE SECTION;
char fname[32],lname[32];
int low,high;
EXEC SQL END DECLARE SECTION;
main()
{
EXEC SQL connect to 'stores_demo';
EXEC SQL prepare sel_stmt from
'select fname, lname from customer
where cust_num between ? and ? for update';
EXEC SQL declare x cursor for sel_stmt;
printf("\nEnter lower limit customer number: ");
scanf("%d", &low);
printf("\nEnter upper limit customer number: ");
scanf("%d", &high);
EXEC SQL open x using :low, :high;
EXEC SQL prepare u from
'update customer set discount = 0.1 where current of x';
while (1)
{
EXEC SQL fetch x into :fname, :lname;
if ( SQLCODE == SQLNOTFOUND) break;
}
printf("\nUpdate %.10s %.10s (y/n)?", fname, lname);
if (answer = getch() == 'y')
EXEC SQL execute u;
EXEC SQL close x;
}
更新 Row 变量(ESQL/C)
带有“集合派生的表”段的 UPDATE 语句允许您在 row 变量中更新字段。“集合
派生的表”段标识要在其中更新字段的 row 变量。要获取更多信息,请参阅 集合
派生表。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1139
要更新字段
1. 在您的 GBase 8s ESQL/C 程序中创建 row 变量。
2. 可选地,以 SELECT 语句(不带有“集合派生的表”段)将 ROW 类型列
选择到 row 变量内。
3. 以 UPDATE 语句和“集合派生的表”段更新 row 变量的字段。
4. 在 row 变量包含正确的字段之后,您使用表或视图名称上的 UPDATE
或 INSERT 语句来将 row 变量保存在 ROW 列(命名的或未命名的)
之中。
UPDATE 语句和“集合派生的表”段允许您在 row 变量中更新字段或字段的组。
请在 SET 子句中指定新的字段值。例如,下列 UPDATE 更改 myrect GBase 8s
ESQL/C row 变量中的 x 和 y 字段:
EXEC SQL BEGIN DECLARE SECTION;
row (x int, y int, length float, width float) myrect;
EXEC SQL END DECLARE SECTION;
. . .
EXEC SQL select into :myrect from rectangles where area = 64;
EXEC SQL update table(:myrect) set x=3, y=4;
假设在 SELECT 语句之后,myrect2 变量有值 x=0、y=0、length=8 以及
width=8。 在 UPDATE 语句之后,myrect2 变量有字段值 x=3、y=4、
length=8,以及 width=8。 您不可使用 INSERT 语句的“集合派生的表”段中
的 row 变量。
然而,您可使用 UPDATE 语句和“集合派生的表”段来将新字段插入到 row 主变
量之内,如果您为该行中的每个字段都指定值的话。
例如,下列代码片段将新的字段值插入到 row 变量 myrect 内,然后将此 row
变量插入到数据库之内:
EXEC SQL update table(:myrect)
set x=3, y=4, length=12, width=6;
EXEC SQL insert into rectangles
values (72, :myrect);

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1140
如果该 row 变量是非类型的变量,则您必须在 UPDATE 之前使用 SELECT,
以便 GBase 8s ESQL/C 可确定这些字段的数据类型。row 变量中字段的
UPDATE 不可包括 WHERE 子句。
row 变量可存储该行的字段值,但它没有与数据库列内在的连接。一旦 row 变量
包含正确的字段值,您必须以下列 SQL 语句之一将该变量保存到 ROW 列内:

要以 row 变量的内容更新表中的 ROW 列,请在表或视图名称上使用
UPDATE 语句并在 SET 子句中指定该 row 变量。(要获取更多信息,
请参阅 更新 ROW 类型列。)

要将 row 插入到列内,请在表或视图名称上使用 INSERT 语句并在
VALUES 子句中指定 row 变量。(要获取更多信息,请参阅 将值插入
到 ROW 类型列内。)
要获取 SPL ROW 变量的示例,请参阅 GBase 8s SQL 教程指南。要获取关于使
用 GBase 8s ESQL/C row 变量的更多信息,请参阅 GBase 8s ESQL/C 程序员手
册 中对复杂数据类型的讨论。

debug 端调试过程中,调用print_var,打印当前存储过程内变量中指定的变量名及其取
值。该函数入参frameno 表示查询遍历的栈层数,支持不加入该参数调用,缺省为查看最上
层栈变量。
表print_var 入参和返回值列表
名称
类型
描述

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
1112
名称
类型
描述
var_name
IN text
变量。
frameno
IN integer(可选)
指定的栈层数,缺省为最顶
层。
varname
OUT text
变量名。
vartype
OUT text
变量类型。
value
OUT text
变量值。
package_name
OUT text
变量对应的package 名,预
留使用,当前均为空。
isconst
OUT boolean
是否为常量。