我在将另一个表中的数据批量插入新表时遇到了一些问题。目标看起来有点像这样:
CREATE TABLE TEST_T (
T_GUID RAW(16) DEFAULT SYS_GUID() NOT NULL,
T_VAL1 NUMBER(10) NOT NULL,
T_VAL2 VARCHAR2(10) NOT NULL,
PRIMARY KEY (T_GUID)
)
我打算用数据填充它的语句的简化版本:
INSERT INTO TEST_T (T_VAL1, T_VAL2)
SELECT DISTINCT
CAST(SUBSTR(zip_code, 1,1) AS NUMBER) as t_val1,
zip_code as t_val2
FROM OTHER_TABLE_T
WHERE ...
ORDER BY t_val1
由于我没有提供一个T_GUID
值,我会假设我得到一个由SYS_GUID
函数为每个新行提供的值。但是出了点问题,我的主键违反了唯一性约束。
如果我删除DISTINCT
,语句成功,但我得到很多重复的条目。而且,当然,如果我SYS_GUID()
在我的SELECT
,结果完全相同。
现在我发现,如果我只是在我SELECT
的周围放另一个,它就可以正常工作,没有违反约束并且插入了不同的行:
INSERT INTO ...
SELECT x.* FROM (
SELECT DISTINCT ...
) x
那么重复的 guid 是从哪里来的呢?如果整组行都没有问题,为什么通过 distinct 删除行会引起麻烦?由于 SYS_GUID 为每个调用创建一个唯一标识符,我只能想象在不同的情况下,它只为整个子句调用一次,这是由周围的 wrapping 解决的SELECT
。如果有人能解释在这种情况下执行有何不同,我会很高兴。