如何在 Oracle 中使用 Union ALL 和 Insert ALL 生成数据?
问题:
您想知道 Union ALL 和 Insert ALL 在生成少量数据时的区别。
解决方案:
我最近一直在生成少量数据以测试某些功能,并在 Oracle 中遇到了几个选项。Union All 和 Insert All 是 Oracle 中常用于生成少量数据的两个选项。
Oracle 中最常见的集合运算符是 UNION 和 UNION ALL。这些运算符用于组合数据集,即使这些集合之间没有关系。
UNION 创建一个不同的集合,而 UNION ALL 允许重复。删除重复项会对性能产生巨大影响,因此理想情况下默认使用 UNION ALL,稍后再处理重复项。
UNION ALL 最常见的用途是生成数据。在 Oracle 中,我们必须始终从某些内容中进行选择,因此有一个名为 DUAL 的特殊伪表。
DUAL 表只有一行,因此如果我们要创建多行,则必须像这样将语句与 UNION ALL 组合在一起
示例
SELECT 'something' FROM DUAL UNION ALL SELECT 'something_else' FROM DUAL UNION ALL SELECT 'something_more' FROM DUAL UNION ALL
我已使用 UNION ALL 生成数据并将其插入到我的目标表中(如下所示)
示例
-- CREATE a table CREATE TABLE tennis_stats ( tennis_player VARCHAR2(100), grandslam_titles NUMBER(2) ); COMMIT;
示例
-- Generating data using Union All INSERT INTO tennis_stats SELECT REGEXP_SUBSTR(t.tennis_stats, '[^,]+', 1, 1) tennis_player, REGEXP_SUBSTR(t.tennis_stats, '[^,]+', 1, 2) grandslam_titles FROM ( SELECT 'ROGER FEDERER' || ',' || 20 AS tennis_stats FROM DUAL UNION ALL SELECT 'RAFAEL NADAL' || ',' || 19 AS tennis_stats FROM DUAL UNION ALL SELECT 'NOVAK DJOKOVIC' || ',' || 17 AS tennis_stats FROM DUAL ) t ; COMMIT;
INSERT ALL
Oracle SQL 具有多表插入操作,可让我们在一条语句中将数据插入多个表中。当我们有一个填充多个目标的源时,多表插入非常有用。
INSERT ALL 语法旨在将数据添加到多个表中,但我通常使用它来生成数据并将多行插入同一张表。
例如,假设我们想使用"插入全部"选项加载上面显示的相同数据。
示例
-- CREATE a table CREATE TABLE tennis_stats ( tennis_player VARCHAR2(100), grandslam_titles NUMBER(2) ); COMMIT;
示例
-- Generating data using Insert All INSERT ALL INTO tennis_stats VALUES ( 'ROGER FEDERER', 20) INTO tennis_stats VALUES ( 'RAFAEL NADAL', 19) INTO tennis_stats VALUES ( 'NOVAK DJOKOVIC', 17) SELECT * FROM dual; COMMIT;
注意 INSERT ALL 不使用序列。INSERT ALL 只会对每个语句增加一次序列,而不是对每个引用增加一次。
INSERT ALL 语句有一个小问题 - 上面的代码没有列出所有列名。在实际的 SQL 语句中,我们不想浪费这么多空间重复相同的列列表。此外,排除列名可以使查询更具前瞻性。
如果 table tennis_stats 的未来版本添加了一个新列,前面的语句将引发异常,而不是默默地写入坏数据。另一方面,列出列名可确保值位于正确的列中,即使列顺序发生变化。排除列名是一种有争议的样式选择。
结论
INSERT ALL 看起来简洁易用,但 UNION ALL 总体上更适合生成数据。 INSERT ALL 语句的解析速度比 UNION ALL 慢,尤其是对于包含数百行的大型语句。
如果我们的应用程序生成大量数据,则 INSERT ALL 比多个 INSERT 语句更好。
总之,Insert ALL 看起来很简洁,但实际上并不适合生成大量数据。