相当于Oracle中不存在的东西?

时间:2017-02-06 15:31:56

标签: oracle exists

以下语句适用于MSSQL:

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'符号......”

4 个答案:

答案 0 :(得分:2)

使用execute immediate在PLSQL块中触发ddl:

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

最接近不存在的是Tom Kyte 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

答案 1 :(得分: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;

答案 2 :(得分: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;
/

答案 3 :(得分:0)

如何执行DDL,并忽略任何&#34;外键已经存在&#34;错误。

不优雅,但不依赖于不更改的密钥名称。