Sql Oracle存储过程变量不工作/表名无效
我正在编写一个存储过程,将数据从中间表插入到另一个表中。我使用动态sql语句,因为我必须在中添加参数变量,因为这将用于多个表/不同的数据。我是plsql新手,这是我第一次尝试编写存储过程。当我硬编码值时,它工作得非常好。我尝试通过在第一个插入行中连接数据库和表变量来添加它们,结果出现错误:Sql Oracle存储过程变量不工作/表名无效,sql,oracle,plsql,Sql,Oracle,Plsql,我正在编写一个存储过程,将数据从中间表插入到另一个表中。我使用动态sql语句,因为我必须在中添加参数变量,因为这将用于多个表/不同的数据。我是plsql新手,这是我第一次尝试编写存储过程。当我硬编码值时,它工作得非常好。我尝试通过在第一个插入行中连接数据库和表变量来添加它们,结果出现错误: ORA-00903: invalid table name ORA-06512: at "ECH_ETL_BATCH_ID.LOOKUP_TABLE_INSERT", line 29 ORA -06512:
ORA-00903: invalid table name
ORA-06512: at "ECH_ETL_BATCH_ID.LOOKUP_TABLE_INSERT", line 29
ORA -06512: at line 14
有什么建议吗
CREATE OR REPLACE PROCEDURE LOOKUP_TABLE_INSERT (
P_SOURCE_DB IN VARCHAR2,
P_SOURCE_TABLE IN VARCHAR2,
P_TARGET_DB IN VARCHAR2,
P_TARGET_TABLE IN VARCHAR2,
P_COLUMN_NAME IN VARCHAR2)
AS
l_sql_statement VARCHAR2 (1000);
BEGIN
l_sql_statement := '
INSERT INTO ' || P_TARGET_DB || '.' || P_TARGET_TABLE || '
(PKEY_SRC_OBJECT,
VERSION_SEQ,
TIMELINE_ACTION,
LAST_UPDATE_DATE,
SRC_ROWID,
HUB_STATE_IND,
ROLE_TP)
SELECT MISSING_VALUES AS PKEY_SRC_OBJECT,
1 AS VERSION_SEQ,
0 AS TIMELINE_ACTION,
INSERT_TS AS LAST_UPDATE_DATE,
''3'' AS "SRC_ROWID",
1 AS "HUB_STATE_IND",
MISSING_VALUES AS ROLE_TP
FROM ECH_ETL_BATCH_ID.Ref_Intermediate
WHERE COLUMN_NM = :COLUMN_NAME
AND LOOKUP_TBL_NM = :TARGET_TABLE';
DBMS_OUTPUT.put_line (l_sql_statement);
EXECUTE IMMEDIATE l_sql_statement USING P_COLUMN_NAME, P_TARGET_TABLE;
COMMIT;
END;
这是一个硬编码版本,工作100%良好:
CREATE OR REPLACE PROCEDURE LOOKUP_TABLE_INSERT (
P_SOURCE_DB IN VARCHAR2,
P_SOURCE_TABLE IN VARCHAR2,
P_TARGET_DB IN VARCHAR2,
P_TARGET_TABLE IN VARCHAR2,
P_COLUMN_NAME IN VARCHAR2)
AS
l_sql_statement VARCHAR2 (1000);
BEGIN
l_sql_statement varchar2(4000) := '
INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP' || '
(PKEY_SRC_OBJECT,
VERSION_SEQ,
TIMELINE_ACTION,
LAST_UPDATE_DATE,
SRC_ROWID,
HUB_STATE_IND, ROLE_TP)
SELECT MISSING_VALUES AS PKEY_SRC_OBJECT,
1 AS VERSION_SEQ,
0 AS TIMELINE_ACTION,
INSERT_TS AS LAST_UPDATE_DATE,
''3'' AS "SRC_ROWID",
1 AS "HUB_STATE_IND",
MISSING_VALUES AS ROLE_TP
FROM ECH_ETL_BATCH_ID.Ref_Intermediate
WHERE COLUMN_NM = ''ROLE_TP''
AND LOOKUP_TBL_NM = ''C_S_LU_PTY_ROLE_TP''';
DBMS_OUTPUT.put_line (l_sql_statement);
EXECUTE IMMEDIATE l_sql_statement;
COMMIT;
END;
这是我用来调用过程的代码:
DECLARE
P_SOURCE_DB VARCHAR2 (200);
P_SOURCE_TABLE VARCHAR2 (200);
P_TARGET_DB VARCHAR2 (200);
P_TARGET_TABLE VARCHAR2 (200);
P_COLUMN_NAME VARCHAR2 (200);
BEGIN
P_SOURCE_DB := NULL;
P_SOURCE_TABLE := NULL;
P_TARGET_DB := NULL;
P_TARGET_TABLE := NULL;
P_COLUMN_NAME := NULL;
ECH_ETL_BATCH_ID.LOOKUP_TABLE_INSERT (
P_SOURCE_DB => ECH_ETL_BATCH_ID,
P_SOURCE_TABLE => Ref_Intermediate,
P_TARGET_DB => ECH_ETL_BATCH_ID,
P_TARGET_TABLE => C_S_LU_PTY_ROLE_TP,
P_COLUMN_NAME => ROLE_TP);
--rollback;
END;
默认情况下,存储过程具有定义者的权限。这意味着,执行过程时可用的唯一特权是授予首先创建过程的用户的特权;而且,只有那些直接(而不是通过角色)授予该用户的特权才可用。在您的情况下,如果您(或编写该过程的人)可以访问有问题的表,ECH_ETL_BATCH_ID.LOOKUP_table_INSERT,在普通SQL语句中,但不是通过存储过程,这可能意味着“您”可以通过授予您的角色的特权访问该表。我有点困惑。我是这个项目的实习生。我编写了存储过程,但我没有权限将其添加到数据库中,因此必须由上级执行此操作。现在我想让它充满活力。如果你告诉我这是某种特权问题,那么当我在值中硬编码时为什么会起作用呢;匿名块只是调用过程,无论名称是硬编码的还是传入的,过程都使用相同的规则。更重要的是,错误是“表名无效”,而不是特权问题中的“表或视图不存在”。我仍然认为它没有得到您认为的
TARGET\u DB
值,因此它试图引用以句点开头的表名。@AlexPoole您是对的。它传入null是因为我用错误的代码调用,所以基本上我是个白痴。谢谢你的帮助。我感谢你的时间。一个人不是白痴的最初迹象之一是当他们称自己为白痴。。。(我应该知道,我一直都这么做!):)