使用 EXECUTE IMMEDIATE 禁用循环中的约束

Use EXECUTE IMMEDIATE to disable constraint in loop

FOR k IN (SELECT UC.CONSTRAINT_NAME, UC.TABLE_NAME FROM USER_CONSTRAINTS UC, TMP_DATA_MIG TDM
WHERE UC.TABLE_NAME = TDM.TABLE_NAMES AND UC.CONSTRAINT_TYPE IN('R','C','U')) LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '||k.TABLE_NAME||' DISABLE CONSTRAINT '||k.CONSTRAINT_NAME||' CASCADE';
END LOOP;

上面的 FOR..IN 循环将 TMP_DATA_MIG 中的那些 table 名称与 USER_CONSTRAINTS 连接起来以获得其相应的约束并禁用它们。

我得到

 ORA-00911  "invalid character"

我尝试使用绑定变量来编写它

FOR k IN (SELECT UC.CONSTRAINT_NAME, UC.TABLE_NAME FROM USER_CONSTRAINTS UC, TMP_DATA_MIG_TABLE_LIST TDM WHERE UC.TABLE_NAME = TDM.TABLE_NAMES AND UC.CONSTRAINT_TYPE IN('R','C','U')) LOOP
l_sql := 'ALTER TABLE :TABLE_NAME DISABLE CONSTRAINT :CONSTRAINT_NAME CASCADE';  
 EXECUTE IMMEDIATE l_sql USING k.TABLE_NAME,k.CONSTRAINT_NAME;
 END LOOP;

以上代码得到ORA-00903 "invalid table name"

我该如何在这两种方法中更正它?

在这种情况下你不能使用 "using"。只需连接字符串并执行即可。

既然这会给您一条错误消息,那么打印您尝试执行的字符串并查看可能导致问题的原因总是有用的。

   for k in (select uc.constraint_name
                   ,uc.table_name
               from user_constraints        uc
                   ,tmp_data_mig_table_list tdm
              where uc.table_name = tdm.table_names
                and uc.constraint_type in ('R', 'C', 'U'))
   loop
      l_sql := 'ALTER TABLE '||k.table_name||'  DISABLE CONSTRAINT '||k.constraint_name||' CASCADE';
      dbms_output.put_line(l_sql);
      execute immediate l_sql;
   end loop;

我找到了根本原因,其中一个约束名称以“_”开头,因此被检测为无效字符。