过程 - 仅在不存在时插入

时间:2013-01-20 22:28:23

标签: oracle plsql

我有插入城市名称的程序(并且还创建下一个id)。如果名称已经存在,如何不允许将城市名称插入表格?谢谢! 有我的代码:

create or replace 
PROCEDURE PlaceName(
          town IN City.Name%TYPE)
AS
  id_C City.Id_City%TYPE;
BEGIN
  SELECT NVL(Max(c.Id_City)+1,1) INTO id_C
  FROM City c;
  INSERT INTO City
  VALUES(id_C, town);
End;

4 个答案:

答案 0 :(得分:4)

我同意Ben的观点,表上应该有一个UNIQUE约束(假设这是一个有效的约束),但使用MERGE语句可以更简单地做到这一点:

MERGE INTO city c
USING ( SELECT 1 FROM dual )
   ON c.name = town
 WHEN NOT MATCHED THEN INSERT ( id, name )
      VALUES ( my_sequence.NEXTVAL, town );

此处并不真正需要USING子句,但它对于合并语句是必需的。

答案 1 :(得分:2)

不,请勿在不存在时插入。这需要两个操作。您必须检查它是否存在,然后您必须插入记录。

正确的方法是在桌面上创建unique constraint。您可以按照文档中的说明进行内联操作,或者如果您的表已经存在,您可以更改它以添加约束:

ALTER TABLE table_name
add CONSTRAINT constraint_name UNIQUE (city);

然后,您可以捕获插入已存在的城市时引发的异常,然后根据获得的信息执行任何操作。

您还错误地增加了ID。您应该使用SEQUENCE,这可以为您节省另一个SELECT。

CREATE SEQUENCE city_seq
     START WITH <current max ID>
   INCREMENT BY 1;

然后您的程序变为:

create or replace procedure PlaceName (
          town in city.name%type ) is

begin
  insert into city
  values(city_seq.nextval, town);

-- Catch the raised exception if the city already exists.
exception when dup_val_on_index then
   <do something>;
end;

答案 2 :(得分:0)

查找Oracle MERGE命令。

答案 3 :(得分:0)

insert into City
  select seq.nextval, town
from dual where not exists (select 1 from City where name = town);

我严格建议使用序列作为人工密钥。 “select nvl(max())”非常非常糟糕。 如果您需要解释,请问我:)