我有插入城市名称的程序(并且还创建下一个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;
答案 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())”非常非常糟糕。 如果您需要解释,请问我:)