如何在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语法旨在向多个表添加数据,但我通常将其用于生成数据并将多行插入同一表。
例如,假设我们想使用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 看起来简洁,但实际上并不适合生成大量数据。