我正在深入研究使用SQL(使用Oracle 11g)的遗留代码(C ++ / Qt)。我已经提供了这段代码(只是更改了变量名称并将其写入多行以获得更好的可读性):
insert into FOO_TABLE (BEGIN, FIRST_VALUE, SECOND_VALUE, VALUE, BAR) select
999,
D.FIRST,
(select O.SECOND from TABLE_TWO O where O.ID=555),
333,
444
from TABLE_ONE D where D.ID=666
这是 INSERT INTO ... SELECT ...
现在看来“select”与insert一起使用以进行retreive并使用单行创建一行。然而,语法似乎很尴尬。我改成了:
insert into FOO_TABLE (BEGIN, FIRST_VALUE, SECOND_VALUE, VALUE, BAR) values (
999,
(select D.FIRST from TABLE_ONE D where D.ID=666),
(select O.SECOND from TABLE_TWO O where O.ID=555),
333,
444)
这个没有任何问题。这是 INSERT INTO ... VALUES ...
在表现方面还是其他方面有什么不同吗?因为第二行对我来说似乎更自然。
答案 0 :(得分:2)
不同之处在于结果集的基数。
无论TABLE_ONE中的行数与D.ID=666
匹配,第一个语句都将起作用。如果返回多行,则第二个语句将失败。
为了完整性,还有第三种变体:
insert into FOO_TABLE (BEGIN, FIRST_VALUE, SECOND_VALUE, VALUE, BAR) select
999,
D.FIRST,
O.SECOND,
333,
444
from TABLE_ONE D
cross join TABLE_TWO O
where O.ID=555
and D.ID=666
Oracle优化器非常聪明,可以知道TABLE_TWO是否匹配唯一键,并相应地制定执行计划。
关于相对表现,所有变化应该是相同的。当然,如果两个查询都返回单行,这就是我所期望的。如果TABLE_ONE返回多行,则可能存在差异。与往常一样,在调优查询时,您必须对每种方法进行基准测试,因为执行时间对数据量和偏差都很敏感。