oracle 错误:创建过程时表或视图不存在

kognpnkq  于 2023-04-20  发布在  Oracle
关注(0)|答案(1)|浏览(279)

我在DB2中执行以下pl/SQL(SQL developer)时遇到一个错误(只是一个名称):

CREATE OR REPLACE PROCEDURE REF_COPY_DB(
v_QUERY_SCHEMA in VARCHAR2
)
AS
    select_columns  VARCHAR(10000);

BEGIN
  insert into v_QUERY_SCHEMA.DATA_COPY_STATUS (DO_NAME, TABLE_NAME, STATUS) VALUES ('test','test','test');
END;
/

错误:

Procedure REF_COPY_DB compiled

LINE/COL  ERROR
--------- -------------------------------------------------------------
8/3       PL/SQL: SQL Statement ignored
8/30      PL/SQL: ORA-00942: table or view does not exist
Errors: check compiler log

我不确定为什么会出现错误表或视图不存在,因为我没有调用过程。我只是在创建过程。我打算用参数DB1调用过程,而DB 1已经有一个名为DATA_COPY_STATUS的表。不确定这是什么原因。
这可能是权限问题吗?如果是,可能需要哪些权限,如何在此处授予权限?此处,我尝试在Schema 2中运行一个过程,该过程将数据插入到Schema 1中的表中

我尝试的事情:

在DATA_COPY_STATUS上对DB 1执行grantinsert,update,delete〈--在DB2上运行此命令
我能够从DB 1上的DB2.DATA_COPY_STATUS查询select *

qyyhg6bp

qyyhg6bp1#

你不能在运行时用静态SQL提供标识符(包括模式、表和列名)。当你编译你的过程时,它在一个名为“V_QUERY_SCHEMA”的模式中查找一个表,这个模式并不存在。
如果需要在运行时提供模式,则需要使用动态SQL:

CREATE OR REPLACE PROCEDURE REF_COPY_DB(
v_QUERY_SCHEMA in VARCHAR2
)
AS
  l_stmt VARCHAR2(4000);
BEGIN
  l_stmt := 'insert into "'
    || dbms_assert.schema_name(v_QUERY_SCHEMA)
    || '".DATA_COPY_STATUS (DO_NAME, TABLE_NAME, STATUS)'
    || ' VALUES (:c1, :c2, :c3)';
  -- to debug
  dbms_output.put_line(l_stmt);
  EXECUTE IMMEDIATE l_stmt USING 'test','test','test';
END;
/

fiddle
我已经使用绑定变量(:c1等,和USING)的部分可以是可变的。模式名称不能是这样的,必须嵌入在语句中。我已经使用DBMS_ASSERT来减轻SQL注入的威胁;注意,传入的值必须是数据字典中出现的模式名称,包括大小写,因此通常(但不一定)大写。
如果您定义的select_columns将在语句中使用,则也需要嵌入;取决于它是如何设置/填充的,你也需要小心注入。我猜你最终会查询数据字典。
另外要记住,默认情况下,过程的所有者必须拥有直接授予的表的特权,而不是通过角色。通过这种设置,过程的调用者不需要能够看到表。如果你想确保调用者必须拥有特权(直接或通过角色),那么你可以看看invoker's rights

相关问题