我想检查cnic是否已经存在,所以永远不要插入cnic

时间:2019-04-24 14:29:00

标签: sql oracle-apex

这是另一种模式,但也有错误

声明 DCNIC varchar(50);

BEGIN
 DCNIC :='';
    Select count(*) into DCNIC from EMPLOYEE where CNIC=:P36_CNIC;
    if DCNIC = 0
    then 
   insert into EMPLOYEE(CNIC) values (DCNIC);
    else
    DCNIC := 1;
    end if;
RETURN DCNIC;
END;

2 个答案:

答案 0 :(得分:0)

请将您的查询1更改为此:

DECLARE
DCNIC VARCHAR(50)
DCNIC :=0;

BEGIN

    if not exists (Select * from EMPLOYEE where CNIC=:P36_CNIC)
    then 
  insert into EMPLOYEE(CNIC) values (DCNIC);
END;

答案 1 :(得分:0)

执行此操作的正确方法是在列上使用unique约束(或索引)。所以:

alter table employee add constraint unq_employee_cnic on employee(cnic);

然后,只需执行insert。如果违反约束,它将失败。如有必要,您可能想在异常失败时捕获该异常。

为什么这是正确的方法?首先,让数据库强制执行数据完整性就是使数据库能够执行其设计要执行的操作。

第二,您的代码引入了竞争条件。两个不同的线程都可以运行if,看到表中没有给定的cnic值,然后 both 都可以插入它。在这种情况下,您将有重复的记录。

第三,您的代码可以防止一个特定的insert。但是,代码中的其他地方可能是另一个不遵循此逻辑的insert。并且,不进行检查。或者,有人可以决定要“修复”数据并意外插入重复项。

第四,您的代码可以防止插入 。但是update也会引入重复值。

让数据库为您完成工作。