Sql Oracle存储过程变量不工作/表名无效

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:

我正在编写一个存储过程,将数据从中间表插入到另一个表中。我使用动态sql语句,因为我必须在中添加参数变量,因为这将用于多个表/不同的数据。我是plsql新手,这是我第一次尝试编写存储过程。当我硬编码值时,它工作得非常好。我尝试通过在第一个插入行中连接数据库和表变量来添加它们,结果出现错误:

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是因为我用错误的代码调用,所以基本上我是个白痴。谢谢你的帮助。我感谢你的时间。一个人不是白痴的最初迹象之一是当他们称自己为白痴。。。(我应该知道,我一直都这么做!):)