在oracle中执行alter存储过程时出现无效表名错误

Posted

技术标签:

【中文标题】在oracle中执行alter存储过程时出现无效表名错误【英文标题】:Invalid table name error, when execute alter stored procedure in oracle 【发布时间】:2017-11-14 11:34:37 【问题描述】:
-- 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:在“SISD_OWNER.CPL_DISABLE_CONSTRAINT”第 5 行

ORA-06512:在第 5 行

    00000 - “无效的表名”

有什么想法吗?

【问题讨论】:

您不能将标识符(=表名)作为参数传递。 该表是否在您当前的架构中? 【参考方案1】:

正如 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”,以使它们与列名分开。您可以在上面的查询中看到它有点混乱.)

我还想指出,在您的函数定义中,您调用第二个参数“constraint_name”,但在匿名块中,您将其称为“column_name”。

【讨论】:

以上是关于在oracle中执行alter存储过程时出现无效表名错误的主要内容,如果未能解决你的问题,请参考以下文章

oracle 执行存储过程时出现卡死

ORACLE PL/SQL 在查询 3 列信息时出现存储过程错误

执行存储过程 NJS-012 时出现 node-oracledb 错误

创建表时出现“ORA-00922:缺少或无效选项”

为 hsqldb 创建架构时出现语法错误

尝试使用 .NET Core 执行存储过程时出现“ORA-03115:不支持的网络数据类型或表示”