PLS 00302:组件 DATA_TYPE 必须在函数中声明

Posted

技术标签:

【中文标题】PLS 00302:组件 DATA_TYPE 必须在函数中声明【英文标题】:PLS 00302 : component DATA_TYPE must de declared in function 【发布时间】:2018-02-28 09:22:55 【问题描述】:

我必须遵循 oracle 函数 build_select,它会创建一个选择请求。返回值格式如下:

select col1 ||'|'||col2 ||'|'||col3 from table;

下面是build_select函数:

create or replace FUNCTION build_select (
  p_table_name   IN VARCHAR2
)
    RETURN VARCHAR2
AS
    l_ret   VARCHAR2 (32767);
BEGIN
    FOR eachcol IN (  SELECT column_name, data_type
                           , LEAD (column_name), LEAD (data_type)
                                 OVER (
                                     PARTITION BY table_name ORDER BY column_id
                                 )
                                 next_column
                        FROM all_tab_cols
                       WHERE table_name = p_table_name
                    ORDER BY column_id)
    LOOP
      IF eachcol.data_type = 'CLOB' THEN
        l_ret   := l_ret || dbms_lob.substr( eachcol.column_name, 3000, 1 ) || CASE WHEN eachcol.next_column IS NULL THEN NULL ELSE ' ||''|''||' END;
      ELSE 
        l_ret   := l_ret || eachcol.column_name || CASE WHEN eachcol.next_column IS NULL THEN NULL ELSE ' ||''|''||' END;
      END IF;
    END LOOP;

    IF l_ret IS NULL
    THEN
        raise_application_error (-20001, 'table ' || p_table_name || ' not found');
    END IF;

    l_ret   := 'select ' || l_ret || ' from ' || p_table_name || ';';

    RETURN l_ret;
END build_select;

我要做的是测试列的数据类型是否为CLOB,如果是则返回为

dbms_lob.substr( eachcol.column_name, 3000, 1 )

我在循环部分添加了 if else 条件。但我得到了错误:

PLS 00302 : component DATA_TYPE must de declared.

有什么帮助吗?

我需要这样做,因为当我对返回的选择进行假脱机时,它没有返回 CLOB 数据类型的所有列。

【问题讨论】:

您发布的代码有错误:LEAD (column_name) 缺少窗口规范。这与您的错误描述不符。修复帖子。 【参考方案1】:

我认为你的功能应该是这样的:

create or replace FUNCTION build_select (
  p_table_name   IN VARCHAR2
)
    RETURN VARCHAR2
AS
    l_ret   VARCHAR2 (32767);
BEGIN
    FOR eachcol IN (  SELECT column_name, data_type
                        FROM all_tab_cols
                       WHERE table_name = p_table_name
                    ORDER BY column_id)
    LOOP
      IF eachcol.data_type = 'CLOB' THEN
        l_ret   := l_ret || 'dbms_lob.substr( '||eachcol.column_name||', 3000, 1 ),';
      ELSE 
        l_ret   := l_ret || eachcol.column_name||',';
      END IF;
    END LOOP;

    IF l_ret IS NULL
    THEN
        raise_application_error (-20001, 'table ' || p_table_name || ' not found');
    END IF;

    l_ret   := 'select ' || regexp_replace(l_ret, ',$', NULL) || ' from ' || p_table_name || ';';

    RETURN l_ret;
END build_select;

注意,ALL_TAB_COLS 还会选择系统生成的隐藏列和不可见列,这可能是一个问题。如果您想过滤它们,请查询ALL_TAB_COLUMNS

【讨论】:

以上是关于PLS 00302:组件 DATA_TYPE 必须在函数中声明的主要内容,如果未能解决你的问题,请参考以下文章

如何纠正“PLS-00302:必须声明组件”错误

PLS-00302:必须声明组件-无法解析

必须声明组件错误 (ORA-06550)

当导入到 oracle 10g 得到错误 6550

我创建了一个过程并在此之后键入,我只是修改了过程光标中的一列并键入

PL\SQL 语句忽略错误