2017-02-06 140 views
0

使用以下語句在MSSQL:相當於Oracle中的IF NOT EXISTS嗎?

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

你需要一個帶有動態SQL的PL/SQL塊 –

+0

謝謝GurV,現在又得到了外鍵已經存在的錯誤。似乎IF有什麼問題。當執行SELECT時,它返回一行,但它仍然試圖執行ALTER ... – Powerslave

回答

1

使用EXECUTE立即解僱PLSQL塊內DDL:

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; 
/

簡單的方法是:

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

您可以在SQL查詢中使用EXISTS,但不能以您嘗試的方式在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,並忽略任何「外鍵已經存在」的錯誤。

不優雅,但不依賴於密鑰名稱不變。