GBase 8s SQL 指南:教程———7修改数据

修改数据

7.1修改数据库中的数据

下列语句修改数据:

DELETE
INSERT
MERGE
UPDATE
当与更高级的SELECT语句相比时,虽然这些SQL语句相对简单,但由于它们更改数据 库的内容,因此请小心使用它们。

如果在查询期间系统硬件或软件岀现故障,请考虑会发生什么。即使对应用程序的影响是 严重的,也不会破坏数据库自身。然而,如果正在进行修改时系统发生故障,则数据库的 状态就不确定了。显然,处于不确定状态的数据库具有深远的影响。在数据库中删除、插 入或更新行之前,请询问自己下列问题:

•用户对数据库及其表的访问是否安全。即,是否将有限的数据库和表级别权限授予 特定用户?

•修改了的数据是否保持数据库现有的完整性?

•系统的状况是否使其对可能导致系统或硬件故障的外部事件具有相对较强的免疫 力?

如果对这些问题不能都回答“是”,也不用担心。对所有这些问题的解决方案都内建在GBase 8s数据库服务器内。在对修改数据的语句进行描述之后,这部分讨论这些解决方案。

7.2删除行

DELETE从表中移除任何行或行的组合。在提交该事务之后,您不可恢复删除了的行。

(在中断了的修改之下讨论事务。现在,请将事务与语句看做是一回事。)

当删除一行时,您还必须小心地删除其值依赖于该删除了的行的其他表的任何行。如果数 据库强制执行引用约束,则您可使用CREATE TABLE或ALTER TABLE语句的ON DELETE CASCADE选项来允许从与另一表的关系中的一个表进行级联删除。要获取关于 引用约束和ON DELETE CASCADE选项的更多信息,请参阅引用完整性。

7.2.1删除表的所有行

DELETE语句指定表并通常包含WHERE子句,该子句指定要从表中移除的一行或多行。 如果省略WHERE子句,则删除所有行。

重要:请不要执行下列语句。

DELETE FROM customer;

您可编写带有或不带FROM关键字的DELETE语句。

DELETE customer;

由于这些DELETE语句不包含WHERE子句,因此从customer表删除所有行。如果您尝 试使用DB-Access菜单选项来进行无条件的删除,则程序会警告您并要求确认。然而,从 程序之内执行无条件的DELETE可在不发出警告的情况下发生。

如果想要从名为from的表中删除行,则您必须首先设置DELIMIDENT环境变量,或使用 其所有者的名称来限定该表的名称:

DELETE legree.from;

要获取关于定界的标识符以及DELIMIDENT环境变量的更多信息,请参阅《GBase 8s SQL 指南:语法》中对“带引号的字符串”表达式以及“标识符”段的描述。

7.2.2使用TRUNCATE来删除所有行

您可使用TRUNCATE语句来快速地从表中移除所有行,同时还移除所有对应的索引数 据。在提交该事务之后,您不可恢复删除了的行。您可对包含任何列类型(包括智能大对 象)的表上使用TRUNCATE语句。

使用TRUNCATE语句来移除行的速度比使用DELETE语句来移除它们快。在

TRUNCATE语句之后,不必立即运行UPDATE STATISTICS语句。成功地执行 TRUNCATE之后,GBase 8s自动地更新该表及其系统目录中的索引的统计信息和分布情 况,以展示在该表中或在它的dbspace分区中没有任何行。

要了解日志记录的描述,请参阅事务日志记录。

TRUNCATE是数据定义语言语句,如果在该表上定义任何触发器,则该语句不激活 DELETE触发器。要了解关于使用触发器的说明,请参阅创建和使用触发器。

如果TRUNCATE语句指定的表是typed表,则成功的TRUNCATE操作从那个表中以 及从该表层级结构内的所有子表中移除所有行和B-tree结构。TRUNCATE不等同于 DELETE语句的ONLY关键字,DELETE语句将操作限制在typed表层级结构内的单个 表。

GBase 8s始终对TRUNCATE操作进行日志记录,即使对非日志记录的表也是如此。在支 持事务日志记录的数据库中,在同一事务之内的TRUNCATE之后,仅SQL的COMMIT WORK或ROLLBACK WORK语句是有效的。要获取关于使用TRUNCATE语句对性能 的影响的信息,请参阅《GBase 8s性能指南》。要了解完整的语法,请参阅《GBase 8s SQL 指南:语法》。

7.2.3删除指定的行

DELETE语句中的 WHERE子句与SELECT语句中的 WHERE子句的形式相同。您可 使用它来准确地指定应删除哪一行或哪些行。您可删除带有特定客户编号的客户,如下例 所示:

DELETE FROM customer WHERE customer_num = 175;

在此示例中,由于customer_num列有唯一约束,因此您可确保只删除一行。

7.2.4删除选择了的行

您还可选取基于非索引列的行,如下例所示:

DELETE FROM customer WHERE company = 'Druid Cyclery';

由于被测试的列没有唯一约束,因此此语句可能删除多行。(Druid Cyclery可能有两个商 店,两个商店的名称相同但客户编号不一样。)

要了解DELETE语句影响多少行,请从customer表中为Druid Cyclery选择符合条件的行 计数。

SELECT COUNT(*) FROM customer WHERE company = 'Druid Cyclery';

您还可选择这些行并显示它们,以确保它们是您想要删除的那些行。

然而,当数据库对于多个用户同时可用时,使用SELECT语句作为测试只是一种近似的方 法。在您执行SELECT语句与后续的DELETE语句之间的时间内,其他用户可能已修改 了该表并更改了结果。在此示例中,另一用户可能执行下列操作:

为名为Druid Cyclery的另一客户插入新行
在插入新行之前,删除一个或多个Druid Cyclery行
•更新Druid Cyclery行以具有新的公司名称,或更新某个其他客户以具有名称 Druid Cyclery o

在这短短的时间间隔内,虽然其他用户不太可能执行这些操作,但确实存在这种可能性。 相同的问题也影响UPDATE语句。在并发和锁定之下讨论解决此问题的方法,且在对多 用户环境编程中讨论得更详细。

您可能遇到的另一个问题是,在该语句完成之前出现硬件或软件故障。在此情况下,数据 库可能还没删除行,可能已删除了一些行,或已经删除了所有指定的行。数据库的状态未 知,这是我们不想看到的。要防止此情况,请使用事务日志记录,如中断了的修改讨论的 那样。

7.2.5删除包含row类型的行

当某行包含定义在ROW类型上的列时,您可使用点符号表示法来指定仅删除那些包含特 定字段值的行。例如,下列语句仅从employee表中删除address列中的city字段的值为San Jose 的那些行:

DELETE FROM employee

WHERE address.city = 'San Jose';

在前面的语句中,address列可能是命名的ROW类型或未命名的ROW类型。您用来指 定ROW类型的字段值的语法是相同的。

7.2.6删除包含集合类型的行

当某行包含定义在集合类型上的列时,您可在集合中搜索特定的元素,并删除在其中找到 那个元素的一行或多行。例如,下列语句删除其中的direct_reports列包含带有元素Baker的 集合的那些行:

DELETE FROM manager

WHERE 'Baker' IN direct_reports;

7.2.7从超级表中删除行

当您删除超级表的各行时,删除操作的作用域是超级表及其子表。假设您创建超级 表person,在其下定义两个子表employee和sales_rep。下列对person表执行的DELETE语 句可从person、employee和sales_rep全部三个表中删除行:

DELETE FROM person

WHERE name ='Walker';

要限制为仅删除超级表的行,您必须使用DELETE语句中的ONLY关键字。例如,下列 语句仅删除person表的行:

DELETE FROM ONLY(person)

WHERE name ='Walker';

重要:当您从超级表中删除行时,请小心使用,因为对超级表的删除的作用域包括该超级表及 其所有子表。

7.2.8复杂的删除条件

DELECT语句中的 WHERE子句可与SELECT语句中的一样复杂。它可包含通过AND 和OR连接的多个条件,且它可能包含子查询。

假设您发现stock表的某些行包含不正确的制造商代码。您不想更新它们,而是想要删除它 们以便重新输入它们。您知道,与正确的那些行不一样,这些行在manufact表中没有相匹 配的行。由于这些不正确的行在manufact表中没有相匹配的行,因此您可以编写下例中所 示的DELETE语句:

DELETE FROM stock

WHERE 0 = (SELECT COUNT(*) FROM manufact

WHERE manufact.manu_code = stock.manu_code);

该子查询对匹配的manufact行数进行计数;对stock的正确的行计数为1,对不正确的行 计数为0。选取不正确的行来删除。

提示: 使用复杂的条件来开发DELETE语句的一种方法是,先开发精确地返回要删除的行的

SELECT语句。将它编写为SELECT *;当它返回所期望的行集时,将SELECT *更改为读 取DELETE,并再执行它一次。

DELETE语句的WHERE子句不可使用测试同一表的子查询。即,当您从stock进行删除 时,您不可在也从stock中选择的WHERE子句中使用子查询。

此规则的关键在于FROM子句。如果在DELETE语句的FROM子句中命名表,则该表 不可还出现在DELECT语句的子查询的FROM子句中。

7.2.9 MERGE 的 Delete 子句

不在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语句的描述。
————————————————
版权声明:本文为CSDN博主「aisirea」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/aisirea/article/details/122999766

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值