2013-04-10 72 views
-1

当我运行下面的插入select语句时,我得到ORA 00937,因为下面的查询无法处理APPLICATIONS表中的一个子选择。我不想硬编码这个值。有什么建议么?ORA 00937同时使用INSERT INTO SELECT

在此先感谢。

insert into CONFIGURATION_PARAMETER_VALUES 
(ID 
, NAME 
, DESCRIPTION 
, DATA_TYPE 
, VALUE_STRING 
, VALUE_INTEGER 
, VALUE_DATE 
, VALUE_FLOAT 
, VALUE_TIMESTAMP 
, APPLICATION_ID 
, DELETED 
) 
select NVL(MAX(ID),0)+1 
     , 'Alert_Statuses_AllExceptNoStatus' 
     , 'Suspicious' 
     , 'String' 
     , 'RBS_EIM_AL_008' 
     , null 
     , null 
     , null 
     , null 
     , (select ID from APPLICATIONS where name = 'Rabobank v 1.0.0.0') 
     , 'N' 
    from CONFIGURATION_PARAMETER_VALUES 
+0

有可能您的子查询返回多个值。所以,试试你的子查询是这样的 从APPLICATIONS中选择MAX(ID)where name ='Rabobank v 1.0.0.0' – IndoKnight 2013-04-10 13:08:53

回答

1

如果不是太晚了,我建议实施SEQUENCE,而不是计数。你可能不会得到严格的数字顺序(可以有差距),但每一次,你会得到一个独特的价值:

CREATE SEQUENCE Config_Parm_Values_Seq START WITH <1 + your current max ID>; 

另外请注意,您的INSERT,因为它代表现在将表现如下:

  • 如果表中没有记录,它将不会插入任何内容。
  • 如果表中有记录,则每次执行时都会使表中的行数增加一倍。

所以,即使你不使用序列,我会考虑一个“普通老”INSERT而不是INSERT ... SELECT。本示例使用以下顺序:

insert into CONFIGURATION_PARAMETER_VALUES 
(ID 
, NAME 
, DESCRIPTION 
, DATA_TYPE 
, VALUE_STRING 
, VALUE_INTEGER 
, VALUE_DATE 
, VALUE_FLOAT 
, VALUE_TIMESTAMP 
, APPLICATION_ID 
, DELETED 
) VALUES (
     Config_Parm_Values_Seq.NEXTVAL -- Use seqname.nextval to get 
             -- the next value from the sequence 
     , 'Alert_Statuses_AllExceptNoStatus' 
     , 'Suspicious' 
     , 'String' 
     , 'RBS_EIM_AL_008' 
     , null 
     , null 
     , null 
     , null 
     , (select MAX(ID) from APPLICATIONS where name = 'Rabobank v 1.0.0.0') 
     , 'N') 
+0

这也是一个有用的解决方案。唯一令我怀疑的是关于序列的使用。这是使用序列的理想选择。但是,填充表格后,我不知道这将如何工作。即使用户执行了“SELECT MAX(ID)+1 FROM ...”,查询也会返回一个错误。 – Rachcha 2013-04-10 14:09:38

+0

Thanks @Rachcha - 我同意你的评价,即序列是理想的,尽管它可能不太适合。我确定'SELECT MAX(ID)+1 ...'可以被调试并且可以工作,可能带有一个'NVL'或者一些其他的后备。然后,如果有多个用户试图运行非 - 序列'INSERT'在同一时间,会导致一个重复的ID?我一直使用序列,所以我不知道会发生什么。 – 2013-04-10 14:23:54

+0

@Rachcha - 感谢'NEXTVAL'的新闻。对我而言,我想我需要另一杯咖啡:)我试图接受你的改变,但不知道如何改变,所以我只是用手工输入。再一次,谢谢。 – 2013-04-10 14:39:09

0

的问题是在你的SELECT声明中,你正在使用SELECT NVL(MAX(ID), 0) + 1。 如您在SELECT列表中使用MAX函数,您必须使用GROUP BY,这不是此处的解决方案。

使用类似以下内容:

insert into CONFIGURATION_PARAMETER_VALUES 
(ID 
, NAME 
, DESCRIPTION 
, DATA_TYPE 
, VALUE_STRING 
, VALUE_INTEGER 
, VALUE_DATE 
, VALUE_FLOAT 
, VALUE_TIMESTAMP 
, APPLICATION_ID 
, DELETED 
) 
select (SELECT MAX(ID) FROM configuration_parameter_values) + 1 
     -- above line instead of NVL(MAX(ID),0)+1 
     -- You can also put NVL function around the subquery. 
     , 'Alert_Statuses_AllExceptNoStatus' 
     , 'Suspicious' 
     , 'String' 
     , 'RBS_EIM_AL_008' 
     , null 
     , null 
     , null 
     , null 
     , (select ID from APPLICATIONS where name = 'Rabobank v 1.0.0.0') 
     -- Warning: The above subquery can generate a TOO_MANY_ROWS exception. 
     -- Use the solution in the other answer to avoid this. 
     , 'N' 
    from CONFIGURATION_PARAMETER_VALUES 
+0

嘿,谢谢你的回复,但是你的查询正在给ORA-00001:唯一约束(CFG_PARAM_VAL_PK)违犯 – user2263807 2013-04-10 13:20:27

+0

这是在'CONFIGURATION_PARAMETER_VALUES.ID'列吗? – Rachcha 2013-04-10 13:30:10

+0

或者你可以尝试'SELECT NVL((SELECT MAX(ID)+1 FROM configuration_parameter_values),1)' – Rachcha 2013-04-10 13:31:59