1

我有插入城市名称(并创建下一个 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

4 回答 4

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这里实际上并不需要该子句,但它对于合并语句是强制性的。

于 2013-01-20T23:29:14.260 回答
2

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

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

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;
于 2013-01-20T22:45:32.657 回答
0
insert into City
  select seq.nextval, town
from dual where not exists (select 1 from City where name = town);

我强烈建议使用序列作为人工键。“选择 nvl(max())” 非常非常糟糕。如果你需要解释,问我:)

于 2013-01-21T07:04:21.890 回答
0

查找 Oracle MERGE 命令。

于 2013-01-20T22:35:08.943 回答