Код запуска, не работающий в oracle, чтобы избежать дублирования данных

#sql #oracle

#sql #Oracle

Вопрос:

Приведенный ниже код запуска (преобразованный из MSSQL) в oracle не работает.

В двух столбцах не должно быть повторяющейся строки в таблице. Я создаю триггер для выполнения этого.

Кто-нибудь может помочь в обновлении / исправлении приведенного выше кода для использования в моем триггере?

 /*
**Unique Constraint for TestOracle - TestTinyInt.
*/
if (Update(UpdOperation) or Update(TestTinyInt)) THEN 
                IF Exists(
                                SELECT * FROM inserted i INNER LOOP JOIN TestOracle x ON 
                                                (i.TestTinyInt=x.TestTinyInt)
                                WHERE i.updoperation IN (0, 1) AND x.updoperation IN (0, 1) GROUP BY x.TestTinyInt
                                HAVING COUNT(*) > 1)
                BEGIN
                                RAISERROR( 'Invalid attempt to enter duplicate TestTinyInt in TestOracle', 16, -1 )
                                ROLLBACK TRAN
                                RETURN
                END
END
  

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

1. Не могли бы вы объяснить это немного подробнее? У вас есть одна таблица и 2 столбца, и из этих 2 столбцов они не должны иметь 2 одинаковых значения? Это правильно?

2. Почему бы вам просто не использовать уникальный индекс? Это будет намного эффективнее

3. Не существует такой вещи, как INNER LOOP JOIN

4. @hakobot да, 1 таблица и 2 столбца и не должно быть ни одной повторяющейся строки …. я хочу создать и использовать триггер для этого, поэтому начал писать код … можете ли вы помочь в исправлении кода?

5. Триггер не будет видеть данные из параллельных транзакций, поэтому это не будет работать надежно.

Ответ №1:

Лучший способ — создать 2 уникальных индекса в каждом из столбцов. Делая это, вы устраняете дублирование в отдельном столбце (как упоминалось @a_horse_with_no_name).

В другом случае вам не нужно использовать triger, вам нужно только простое условие where

 where Column_A not in (select Column_B from table) and Column_B not in (Select Column_A in table).
  

Редактировать:
Это если нужно сделать в триггере, ТО :

   create or replace trigger ... instead of insert or update on ...
    Declare
    dummy number;
    Begin
     select 1 into dummy from dual where :new.Column_A in  (select Column_B from table) or new:.Column_B in (Select Column_A in table);
    if dummy <> 1 THEN 
      INSERT 
    END IF;
    END;
  

EDIT2: ЕСЛИ вам не нужны уникальный индекс и tirgger, вот решение :

  create or replace trigger ... instead of insert or update on ...
    Declare
    dummy number;
    Begin
    select count(*)  into dummy from( 
    SELECT COL1 FROM (
    (select :new.Column_A col1 from  dual  
      UNION 
    select :new.Column_B from dual))
   INTERSECT 
    SELECT COL2 FROM (         
   ( SELECT COLUMN_A COL2 from table 
       UNION
    SELECT COLUMN_B from table));

    if dummy = 0 THEN 
      INSERT 
    END IF;
    END;
  

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

1. @a_horse_with_no_name …. спасибо, что поделились индексом … но мне просто нужно, чтобы этот код запуска работал на меня …. если возможно, пожалуйста, помогите

2. @hakobot … спасибо за помощь .. однако мне нужно, чтобы этот код запуска работал… и выполнить это с помощью триггера… пожалуйста, помогите там… необходимо преобразовать его..

3. @hakobot .. еще раз спасибо .. но все же моя проблема не решена, поскольку вы предлагаете новый код триггера или индексы и т.д. … Однако то, что я искал, это просто исправить приведенный выше код триггера … вот и все … особенно «если существует» и т.д.

4. @rock_techie Проблема в том, что я понятия не имею, какой код у вас. Я не знаю, как это работает (или даже если это работает) 🙂 Я никогда не видел «СОЕДИНЕНИЕ с ВНУТРЕННИМ циклом», и я сомневаюсь, что есть что-то подобное. Это причина, по которой я написал свой собственный код. С уважением

5. @hakobot … спасибо… этот код был преобразован из mssql в oracle …. кто-нибудь еще может помочь просто преобразовать этот триггер?