【问题标题】:ORA-00904 - Invalid Identifier in Dynamic SQLORA-00904 - 动态 SQL 中的标识符无效
【发布时间】:2020-02-17 16:10:50
【问题描述】:

我正试图找出我在存储过程中遇到的ORA-00904 - Invalid Identifier 错误。

代码如下:

CREATE OR REPLACE PROCEDURE CDG4_HIER_GET_SUBTREE(pDimensionId IN VARCHAR2, pPeriodId IN NUMBER, pNodeId IN NUMBER, pMode IN CHAR, rCursor OUT SYS_REFCURSOR) IS

v_table_name VARCHAR2(30);
v_function_name VARCHAR2(30) := 'CDG4_HIER_MGR_HAS_CHILDREN'; -- some function defined in the same package
InvalidMode EXCEPTION;
---
v_sql VARCHAR2(2000);

BEGIN

-- Get dynamic table name
v_sql := 'SELECT UPPER(TABLE_ID)'
      ||'FROM CDG4_CFG_MAP_GER '
      ||'WHERE UPPER(DIMENSION_ID) = UPPER(''' || pDimensionId || ''') ';

EXECUTE IMMEDIATE v_sql INTO v_table_name;

IF pMode = 'F' THEN

    -- Do something

ELSIF pMode = 'S' THEN

    v_sql := 'SELECT A.PERIODO_K, '
           ||'      A.FIGLIO_K, '
           ||'      A.PADRE_K, '
           ||'      A.F_LAYOUT, '
           ||'      A.F_VISUALIZZA, '
           ||'      DECODE(A.PADRE_K, NULL, NULL, B2.CODICE) AS CODICE_PADRE, '
           ||'      A.F_ORDINE, '
           ||'      DECODE(A.GEN1, ''2'', ''I'', A.GEN1) AS GEN1, '
           ||'      A.GEN2, '
           ||'      A.GEN3, '
           ||'      ''[''|| B1.CODICE || ''] - '' || B1.DESCR AS DESCR, '
           ||'      ''[''|| B1.CODICE || ''] - '' || B1.DESCR AS DESCRIZIONE, '
           ||'      ' || v_function_name || '(''' || pDimensionId || ''', ' || pPeriodId || ', A.FIGLIO_K) AS HAS_CHILDREN '
           ||'FROM DM_GERARCHIE A, DIM_BO_CANALE_PRIMARIA B1, DIM_BO_CANALE_PRIMARIA B2 '
           ||'WHERE A.FIGLIO_K = B1.CODICE_K '
           ||'AND A.PADRE_K = B2.CODICE_K '
           ||'AND UPPER(A.DIMENSION_ID) = UPPER(''' || pDimensionId || ''') ' 
           ||'AND UPPER(B1.DIMENSION_ID) = UPPER(''' || pDimensionId || ''') ' 
           ||'AND UPPER(B2.DIMENSION_ID) = UPPER(''' || pDimensionId || ''') '
           ||'AND A.PERIODO_K = ' || pPeriodId
           ||' AND A.FIGLIO_K = ' || pNodeId;

ELSE 

    RAISE InvalidMode;

END IF;

OPEN rCursor FOR v_sql;

EXCEPTION
WHEN InvalidMode THEN
RAISE_APPLICATION_ERROR(-20005, 'Invalid selection mode.');
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20004, 'Generic error - '||SQLCODE||' -ERROR- '||SQLERRM);

END;

Oracle 似乎无法识别函数v_function_name(它在同一个包中),因为它在打开游标rCursor 时不断返回ORA-00904。

对这种行为的合理条款有任何暗示吗?

提前致谢。

【问题讨论】:

  • 好吧,您可能在某处打错了字,但这里没有人能够破译该字符串。打印出 v_str 的值并尝试从 sqlplus 或其他 sql 客户端运行它。此外,您不应该将查询参数作为文字放在字符串中。查看“USING”子句。这将消除很多双/三引号

标签: oracle plsql oracle11g dynamic-sql


【解决方案1】:

Oracle似乎无法识别函数v_function_name(在同一个包中

动态 SQL 作为 SQL 执行,但超出了包的范围。这意味着我们需要构建一个有效的 SQL 语句。如果您正在运行类似的静态 SELECT 语句,您将编写 package_name.v_function_name,因为您的 SQL 将在包外执行。这就是你需要在这里做的。


虽然现在我更仔细地查看了您的代码,但我完全不明白您为什么要使用动态 SQL。您可以使用绑定变量和参数将语句作为静态 SQL 执行。

OPEN rCursor FOR 
    SELECT A.PERIODO_K, 
           A.FIGLIO_K, 
           A.PADRE_K, 
           A.F_LAYOUT, 
           A.F_VISUALIZZA, 
           DECODE(A.PADRE_K, NULL, NULL, B2.CODICE) AS CODICE_PADRE, 
           A.F_ORDINE, 
           DECODE(A.GEN1, ''2'', ''I'', A.GEN1) AS GEN1, 
           A.GEN2, 
           A.GEN3, 
           '[' || B1.CODICE || '] - ' ||  B1.DESCR AS DESCR, 
           '[' || B1.CODICE || '] - ' || B1.DESCR AS DESCRIZIONE, 
            package_name.v_function_name (pDimensionId ,pPeriodId , A.FIGLIO_K) AS HAS_CHILDREN 
      FROM DM_GERARCHIE A, DIM_BO_CANALE_PRIMARIA B1, DIM_BO_CANALE_PRIMARIA B2 
      WHERE A.FIGLIO_K = B1.CODICE_K 
      AND A.PADRE_K = B2.CODICE_K 
      AND UPPER(A.DIMENSION_ID) = UPPER( pDimensionId )  
      AND UPPER(B1.DIMENSION_ID) =  UPPER( pDimensionId )  
      AND UPPER(B2.DIMENSION_ID) = UPPER( pDimensionId )  
      AND A.PERIODO_K = pPeriodId
      AND A.FIGLIO_K = pNodeId;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多