Я хочу проверить, существует ли cnic уже, он никогда не вставляет cnic

#sql #oracle-apex

#sql #oracle-apex

Вопрос:

Это другой шаблон, но в нем также есть ошибки

ОБЪЯВИТЕ переменную DCNIC(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;
  

Комментарии:

1. Это MySQL или Oracle?

2. Это Sql-запрос, но в нем так много ошибок

Ответ №1:

Пожалуйста, измените свой запрос 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. ORA-06550: строка 1, столбец 106: PLS-00103: Столкнулся с символом «ОБЪЯВИТЬ» при ожидании одного из следующих: (- case mod new not null <идентификатор> <идентификатор с разделителями в двойных кавычках> <переменная привязки> продолжить среднее значение текущего значения существует макс мин. предыдущее отклонение суммы sql stddev выполняется для всего времени слияния интервал времени дата <строковый литерал со спецификацией набора символов> <число> <строка SQL в одинарных кавычках> труба

2. ОБЪЯВИТЕ DCNIC varchar(50); НАЧНИТЕ DCNIC :=»; Выберите count(*) в DCNIC из EMPLOYEE, где CNIC =:P36_CNIC; если DCNIC = 0, затем вставьте в значения EMPLOYEE (CNIC) (DCNIC); иначе DCNIC : = 1; завершите, если; ВЕРНИТЕ DCNIC; END; Это другой шаблон, но в нем также есть ошибки

Ответ №2:

Правильный способ сделать это — иметь unique ограничение (или индекс) для столбца. Итак:

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

Затем просто выполните insert . Произойдет сбой, если ограничение будет нарушено. При необходимости вы можете перехватить исключение при сбое.

Почему это правильный способ? Во-первых, обеспечение целостности данных с помощью базы данных позволяет базе данных выполнять то, для чего она предназначена.

Во-вторых, ваш код вводит условия гонки. Два разных потока могли бы оба запустить if , увидеть, что заданного cnic значения нет в таблице, а затем оба могли бы вставить его. В этом случае у вас будут дубликаты.

В-третьих, ваш код защищает от одного конкретного insert . Однако где-то еще в коде может быть другой, insert который не следует этой логике. И проверка не выполняется. Или кто-то может решить, что они хотят «исправить» данные и случайно вставить дубликаты.

В-четвертых, ваш код защищает от вставок. Но update s также может вводить повторяющиеся значения.

Позвольте базе данных выполнить работу за вас.