删除索引或约束而不知道Oracle的名称

时间:2012-01-25 18:51:24

标签: sql oracle constraints sql-drop

在oracle数据库中,我有一个外键,不知道它的名字,只有column_name和reference_column_name。 我想写一个sql脚本,如果它存在,应该删除这个外键,所以这是我使用的代码:

declare
 fName varchar2(255 char);
begin
 SELECT x.constraint_name into fName FROM all_constraints x
 JOIN all_cons_columns c ON
 c.table_name = x.table_name AND c.constraint_name = x.constraint_name
 WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
end;

此脚本的输出是"匿名块已完成",所以它成功了,但是当我添加了drop部分时:

declare
 fName varchar2(255 char);
begin
 SELECT x.constraint_name into fName FROM all_constraints x
 JOIN all_cons_columns c ON
 c.table_name = x.table_name AND c.constraint_name = x.constraint_name
 WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
 if (fName != '') THEN
  alter table MY_TABLE_NAME drop constraint fName;
 end if;
end;

然后我得到了这个:

  

错误报告:ORA-06550:第9行,第5列:PLS-00103:遇到了   符号" ALTER"期待以下之一:

     如果loop mod null pragma raise,

开始case声明退出goto   使用<<返回选择更新关闭当前删除   fetch lock insert open rollback savepoint set sql execute commit   forall合并管   06550. 00000 - "行%s,列%s:\ n%s"   *原因:通常是PL / SQL编译错误。   *操作:

所以有人能告诉我这里的问题是什么吗?

我还尝试将所有内容都放入函数中:

declare
  function getFName return varchar2 is
    fName varchar2(255 char);
  begin
   SELECT x.constraint_name into fName FROM all_constraints x
   JOIN all_cons_columns c ON
   c.table_name = x.table_name AND c.constraint_name = x.constraint_name
   WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';

   return fName;
  end;
begin
  if getFName() != '' then
   alter table all_events drop constraint getFName(); 
  end if;
end; 

结果是由语句" alter table"

引起的同样错误

这个也没有帮助:

alter table all_events drop constraint
   (SELECT x.constraint_name into fName FROM all_constraints x
   JOIN all_cons_columns c ON
   c.table_name = x.table_name AND c.constraint_name = x.constraint_name
   WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME');

输出结果为:

  

错误报告:SQL错误:ORA-02250:缺少或无效的约束名称   02250. 00000 - "缺少或无效的约束名称"   *原因:约束名称丢失或无效。   *操作:为约束名称指定有效的标识符名称。

对于sql server(MS SQL),这样做很容易。只需使用@声明一个变量并设置它,然后使用它。在oracle上,我不知道它不起作用......

2 个答案:

答案 0 :(得分:6)

除了不能在PL / SQL块中直接执行DDL之外,原始版本大多数都没有问题。相反,你必须将它包装在EXECUTE IMMEDIATE

execute immediate 'alter table MY_TABLE_NAME drop constraint "' || fName || '"';

即使在编译时知道约束名称也是如此,但在你的情况下它是双重的,因为fName不是约束名,而是包含约束的变量-name。

另外,这个:

if (fName != '') THEN

无效/有意义,因为在Oracle中''表示NULL。你应该写

IF fName IS NOT NULL THEN

代替。

答案 1 :(得分:2)

这是如何删除列中键入“R”的所有约束:

begin
    FOR rec IN (SELECT x.constraint_name fName FROM all_constraints x
        JOIN all_cons_columns c ON
        c.table_name = x.table_name AND c.constraint_name = x.constraint_name
        WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME')
    LOOP
        EXECUTE IMMEDIATE 'ALTER TABLE MY_TABLE_NAME DROP CONSTRAINT "' || rec.fName || '"';
    END LOOP;
end;