INSERT返回IDENTITY生成ORA 00933

时间:2015-09-19 15:17:24

标签: sql oracle plsql

我试图将单个记录插入表中并返回通过ASP.net/Visual Studio添加到记录中的序列号。但是,我收到了上面提到的错误。最初我认为我的错误是因为它认为我可能会返回多个记录,但即使重写了几种方法,错误仍然存​​在。此主题上存在多个帖子,但它们似乎都围绕着插入多个记录的可能性。

我怀疑是因为我正在使用"选择...来自双"它仍然认为我可以插入多个记录。我显然不需要"选择......来自双重"除了我想使用WHERE子句来保证记录在目标表中不存在。

非常感谢任何帮助或建议。谢谢。

INSERT INTO blatchildren
  (blatranscriptid, childactivityid, enrollmentDate, enrollmentStatus)
  SELECT 2,
                 'cours000000000004981',
                 to_date('1/1/2015 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM'),
                 'E'
    from dual
   where 'cours000000000004981' not in (select childactivityid from blatchildren) 
   returning id
    into :identity

为了测试代码,我在PL / SQL Developer中运行了以下代码:

declare identity number(2);
begin
INSERT INTO blatchildren
  (blatranscriptid, childactivityid, enrollmentDate, enrollmentStatus)
  VALUES( 2,
         'cours000000000004981',
         to_date('1/1/2015 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM'),
         'E')
  returning id
    into identity;
end;

2 个答案:

答案 0 :(得分:2)

您不能在PL / SQL中使用RETURNING子句INSERT .. SELECT

insert_into_clause
{ values_clause [ returning_clause ]
| subquery 
} [ error_logging_clause ]

returning_clause只能与values_clause

一起提供

请参阅:https://docs.oracle.com/database/121/SQLRF/statements_9014.htm#SQLRF55051

更好的方法可能是向UNIQUE

添加blatchildren(childactivityid)约束

答案 1 :(得分:0)

我完全同意Luka Eder的回答,但是如果你必须使用带有return子句的单个查询,它将如下所示:

variable identity number;
BEGIN
INSERT INTO blatchildren
  (blatranscriptid, childactivityid, enrollmentDate, enrollmentStatus)
  VALUES ((SELECT 2 from dual where 'cours000000000004981' not in (select childactivityid from blatchildren)),
          (SELECT 'cours000000000004981' from dual where 'cours000000000004981' not in (select childactivityid from blatchildren)), 
          (SELECT to_date('1/1/2015 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM') from dual where 'cours000000000004981' not in (select childactivityid from blatchildren)), 
          (SELECT 'E'  from dual where 'cours000000000004981' not in (select childactivityid from blatchildren)))
   returning blatranscriptid
    into :identity;
END;
/

这里的逻辑是,正如Luka所说,你必须使用VALUES子句来使RETURNING工作。请注意我放在那里的父母的数量。在一个值子句中做一个选择是可能的,我个人从来没有用这种方式写过东西,我相信我只会查询数据库两次。

P.S。这并没有解决太多,你仍然有插入尝试。 但也许它可以节省添加另一个约束,可能你在id列上有一个非空约束。