2017-02-06 16 views
0

следующее заявление работает в MSSQL:Эквивалент IF НЕ СУЩЕСТВУЕТ в Oracle?

IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[FK_StationObjectsID]') AND parent_object_id = OBJECT_ID(N'[Attendance]')) 
BEGIN 
    ALTER TABLE Attendance ADD CONSTRAINT FK_StationObjectsID FOREIGN KEY (StationObjectsID) REFERENCES stationobjects (stationobjectsid) 
END 

В Oracle я попробовал:

IF NOT EXISTS (SELECT * FROM USER_CONSTRAINTS WHERE CONSTRAINT_NAME = 'FK_STATIONOBJECTSID' AND TABLE_NAME = 'ATTENDANCE') THEN 
BEGIN 
    ALTER TABLE Attendance ADD CONSTRAINT FK_StationObjectsID FOREIGN KEY (StationObjectsID) REFERENCES stationobjects (stationobjectsid); 
END; 

но его дает мне ошибку PLS-00103 "встретившиеся символ 'ALTER' ..."

+0

Попробуйте «выполнить немедленный» вариант. , .'' – GurV

+0

Вам нужен блок PL/SQL с динамическим SQL для этого –

+0

Спасибо GurV, теперь получаем еще одну ошибку, что внешний ключ уже существует. Кажется, что что-то не так с IF. При выполнении SELECT возвращает одну строку, но все еще пытается выполнить ALTER ... – Powerslave

ответ

1

Использование выполнить немедленный огонь DDL внутри PLSQL блока:

IF <condition> THEN 
    Execute immediate 'ALTER TABLE . . .'; 
END if; 

Ближайшие что приходят не существует, метод дал Том Кайта here

begin 
    for i in (select count(*) cnt from dual 
      where not exists (
       SELECT * 
       FROM USER_CONSTRAINTS 
       WHERE CONSTRAINT_NAME = 'FK_STATIONOBJECTSID' 
       AND TABLE_NAME = 'ATTENDANCE' 
      )) loop 
      if (i.cnt = 1) then 
       execute immediate 'ALTER TABLE Attendance ADD CONSTRAINT FK_StationObjectsID FOREIGN KEY (StationObjectsID) REFERENCES stationobjects (stationobjectsid)'; 
      end if; 
    end loop; 
end; 
/

Simpler метод будет:

declare 
    n int := 0; 
begin 
    select count(*) into n 
    from user_constraints 
    where constraint_name = 'FK_STATIONOBJECTSID' 
    and table_name = 'ATTENDANCE'; 
    if n = 0 then 
    execute immediate 'ALTER TABLE Attendance ADD CONSTRAINT FK_StationObjectsID FOREIGN KEY (StationObjectsID) REFERENCES stationobjects (stationobjectsid)'; 
    end if; 
end; 
/

См - https://dba.stackexchange.com/questions/37362/why-cant-we-write-ddl-statement-directly-into-the-pl-sql-block

0

Понял работает, возможно, не самый лучший решение:

DECLARE 
    foreign_key_exists number := 0; 
BEGIN 
    SELECT COUNT(*) INTO foreign_key_exists FROM USER_CONSTRAINTS WHERE upper(CONSTRAINT_NAME) = upper('FK_StationObjectsID') AND upper(TABLE_NAME) = upper('Attendance'); 
    IF (foreign_key_exists = 0) 
    THEN 
     EXECUTE IMMEDIATE 'ALTER TABLE Attendance ADD CONSTRAINT FK_StationObjectsID FOREIGN KEY (StationObjectsID) REFERENCES stationobjects (stationobjectsid)'; 
    END IF; 
END; 
/
1

Вы можете использовать EXISTS в SQL-запросе, но не в PLSQL-состоянии, как вы пытались.

Вам может понадобиться следующее:

declare 
    vCheck number; 
begin 
    select count(1) 
    into vCheck 
    from user_constraints 
    where constraint_name = 'FK_STATIONOBJECTSID' 
     and table_name = 'ATTENDANCE'; 
    -- 
    if vCheck = 0 then 
     execute immediate 'ALTER TABLE Attendance ADD CONSTRAINT FK_StationObjectsID FOREIGN KEY (StationObjectsID) REFERENCES stationobjects (stationobjectsid)'; 
    end if; 
end; 
0

Как о выполнении DDL, и игнорирование любой «внешний ключ уже существует» ошибка.

Не изящно, но не зависит от имени ключа, которое не меняется.

 Смежные вопросы

  • Нет связанных вопросов^_^