在oracle中执行alter storage procedure时,表名错误无效

时间:2017-11-14 11:34:38

标签: oracle

-- Disable constaint, good
CREATE OR REPLACE PROCEDURE cpl_disable_constraint(table_name IN varchar2, constraint_name IN varchar2)
AS

BEGIN
   execute immediate 'ALTER TABLE :1 DISABLE CONSTRAINT :2' using table_name, constraint_name;
END;
/


-- Bug
declare
  table_name varchar2(100) := 'ADV_TEST_COURSE_CREDIT';
  column_name varchar2(100) := 'SEQUENCE_NUMBER';
begin
  cpl_disable_constraint(table_name, column_name);
end;
/

我收到了这些错误:

  

ORA-00903:表名无效

     

ORA-06512:at" SISD_OWNER.CPL_DISABLE_CONSTRAINT",第5行

     

ORA-06512:第5行

     
      
  1. 00000 - "表格名称无效"
  2.   

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

如提及a_horse_with_no_name,您无法将标识符作为参数传递给execute immediate。你必须把它放在SQL语句中。

execute immediate 'ALTER TABLE ' || table_name || ' DISABLE CONSTRAINT :1' using constraint_name;

请注意,如果您不仔细验证table_name变量,这将打开SQL注入。我通常在调用execute immediate之前做这样的事情,以确保table_name变量是约束的有效和正确的表名,而不是像null; DROP TABLE ADV_TEST_COURSE_CREDIT;这样的恶意字符串:

select c.table_name into table_name from user_constraints c where c.constraint_name = constraint_name;

(顺便说一句,这是为什么人们经常为本地PL / SQL变量名选择前缀的原因之一,例如" v_table_name",以使它们与列名分开。你可以看到它&#39 ;在上面的查询中有点混乱。)

另外我想指出,在您的功能定义中,您要调用第二个参数" constraint_name",但是在匿名块中,您可以调用它和" #34;列名&#34 ;.