返回首页

gbase数据、南大通用产品文档:GBase8sMERGE 的 Delete 子句

更新日期:2024年09月11日

不在 WHERE 子句中编写子查询,您可使用 MERGE 语句将来自源表和目标表的行连接
在一起,然后从目标删除与连接条件相匹配的那些行。(Delete MERGE 中的源表还可为
一个集合派生的表,它的行是查询的结果,该查询连接其他的表和视图,但是在下列的示
例中,源是单个表。)
如在前面的示例中那样,
假设您发现 stock 表的某些行包含不正确的制造商代码。
您想要删
除它们以便重新输入它们,而不是更新它们。您可使用 MERGE 语句,指定 stock 作为目
标表,manufact 作为源表,ON 子句中的连接条件,并对于带有不正确的制造商代码
的 stock 行使用 Delete 子句,如下例所示:
MERGE INTO stock USING manufact
ON stock.manu_code != manufact.manu_code
WHEN MATCHED THEN DELETE;
在此示例中,会从 stock 表中删除那些满足 ON 子句中的连接条件的所有行。在此,对于
其中的 manu_code 列值不等于 manufact 中的任何manu_code 值的 stock 的那些行,连接条
件中的不等谓词(stock.manu_code != manufact.manu_code)求值为真。
在 USING 子句中必须罗列正连接到目标表的源表。
MERGE 语句还可更新目标表的行,
或将数据从源表插入到目标表,
根据该行是否满足 ON
子句为连接目标表与源表而指定的条件。单个 MERGE 语句还可同时组合 DELETE 与
INSERT 操作,或者可同时组合 UPDATE 与 INSERT 操作而不删除任何行。MERGE 语
句不更改源表。要获取关于 Delete 合并、Insert 合并和 Update 合并的语法与限制的更多
信息,请参阅《GBase 8s SQL 指南:语法》 中 MERGE 语句的描述。

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 161 -

当您使用由程序逻辑补充的游标时,您可解决普通的 SQL 不可解决的问题。这些问题之
一就是部件爆炸问题,有时称为材料单处理。此问题的核心是对象之间的递归关系;一个
对象包含其他对象,其又包含其他对象。
通常以制造库存为例来说明该问题。例如,公司制造各种部件。有些部件是分立的,但有
些是其他部件的组合。
在可能称为 contains 的单个表中说明这些关系。列 contains.parent 持有系组合的部件的部件
编号。列 contains.child 具有为父部件的组件的部件的部件编号。如果部件编号 123400 是
九个部件的组合,则存在九行,123400 在第一列中,其他部件编号在第二列中。下图展示
描述部件编号 123400 的多行中的一行。
图: 部件爆炸问题


部件爆炸问题在于:给定一个部件编号,产生为那个部件的组件的所有部件的列表。下列
示例是一种解决方案的概要,如以 GBase 8s ESQL/C 实现的那样:
int part_list[200];

boom(top_part)
int top_part;
{
long this_part, child_part;
int next_to_do = 0, next_free = 1;
part_list[next_to_do] = top_part;

EXEC SQL DECLARE part_scan CURSOR FOR
SELECT child INTO child_part FROM contains

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司
- 222 -
WHERE parent = this_part;
while(next_to_do < next_free)
{
this_part = part_list[next_to_do];
EXEC SQL OPEN part_scan;
while(SQLCODE == 0)
{
EXEC SQL FETCH part_scan;
if(SQLCODE == 0)
{
part_list[next_free] = child_part;
next_free += 1;
}
}
EXEC SQL CLOSE part_scan;
next_to_do += 1;
}
return (next_free - 1);
}
从技术上讲,contains 表的每一行都是有向无环图,或树,的头结点。该函数执行对该树的
宽度优先搜索,树根是作为它的参数传递的部件编号。该函数使用名为 part_scan 的游标返
回在 parent 列中带有特定的值的所有行。最内层的 while 循环打开 part_scan 游标,在选择
集中访存每一行,并当已检索了每一组件的部件编号时,关闭该游标。
此函数解决部件爆炸问题的核心,但该函数不是完整的解决方案。例如,它不允许组件在
树中出现多个级别。此外,实际的 contains 表还会有列count,给出在每一 parent 中使用
的 child 部件的计数。返回每一组件部件的总计数的程序要复杂得多。
之前描述的迭代方法不是解决部件爆炸问题的唯一方法。如果代的数目有固定的限制,则
您可使用嵌套的外部自连接,以单个 SELECT 语句解决该问题。
如果在一个最高级别部件内,可包含最多四代部件,则下列 SELECT 语句返回所有部件:

SELECT a.parent, a.child, b.child, c.child, d.child
FROM contains a
OUTER (contains b,
OUTER (contains c, outer contains d) )
WHERE a.parent = top_part_number
AND a.child = b.parent
AND b.child = c.parent

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司
- 223 -
AND c.child = d.parent
此 SELECT 语句为来源于指定为 top_part_number 的祖先的每一行返回一行。对于不存在
的级别,返回 Null 值。
(请使用指示符变量来检测它们。)要将此解决方案扩展到更多级
别,请选择 contains 表的附加的嵌套外部连接。您还可修订此解决方案来返回每一级别上
部件的数目的计数。


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 795
使用 RENAME DATABASE 语句来更改数据库的名称。此语句为对 SQL 的
ANSI/ISO 标准的扩展。
语法

元素
描述
限制
语法
new_database 您在此为
old_database
声明的新名称
必须在当前数据库服务器的数据
库名称之中为唯一的;当发出此
语句时,必须未被任何用户打开
数据库名
old_database new_database
替代的名称
必须在当前数据库服务器上存
在,但它不可为当前数据库的名

数据库名
owner
old_database
的所有者
必须为该数据库的所有者
所有者名

用法
如果下列条件之一为真,则您可重命名数据库:

您创建了该数据库。

您有对该数据库的 DBA 权限。
然而,如果指定的数据库包含任何下列对象,则 RENAME DATABASE 语句失
败,并报错 -9874:

虚拟表

虚拟索引

R-tree 索引

在用户定义的主访问方法中或在用户定义的辅助访问方法中,引用数据库
的当前名称的 DataBlade。
您仅可重命名您当前连接到的数据库服务器的数据库。
您不可从 SPL 例程之内重命名数据库。

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