【问题标题】:how to return a dynamic result set in Oracle function如何在 Oracle 函数中返回动态结果集
【发布时间】:2011-04-29 09:14:12
【问题描述】:

我在网上找到了一个字符串分词器查询,并将其打包到下面的函数中,该函数返回动态的令牌集。该函数编译成功,但不知何故我收到错误“ORA-00933:SQL 命令未正确结束”。有人可以帮我调试吗?谢谢。

CREATE OR REPLACE TYPE KEY_VALUE_TYPE is object (k varchar2(4000), v varchar2(4000));
CREATE OR REPLACE TYPE KEY_VALUE_TABLE is table of key_value_type;
CREATE OR REPLACE FUNCTION StrTokenizer
        (string IN VARCHAR2, delimiter IN VARCHAR2)
RETURN key_value_table AS
    v_ret key_value_table;
BEGIN
    SELECT
        CAST( 
            multiset(
            SELECT
                LEVEL  k, 
                SUBSTR(STRING_TO_TOKENIZE, 
                    DECODE(LEVEL, 1, 1, INSTR(STRING_TO_TOKENIZE, DELIMITER, 1, LEVEL-1)+1), 
                    INSTR(STRING_TO_TOKENIZE, DELIMITER, 1, LEVEL) 
                        - DECODE( LEVEL, 1, 1, INSTR(STRING_TO_TOKENIZE, DELIMITER, 1, LEVEL-1)+1)) v
            FROM
                (
                    SELECT
                        ':string'||':delimiter' AS STRING_TO_TOKENIZE , ':delimiter' AS DELIMITER
                    FROM
                        DUAL
                )
            CONNECT BY INSTR(STRING_TO_TOKENIZE, DELIMITER, 1, LEVEL)>0 
            ORDER BY level ASC) 
        As key_value_table)
    INTO
        v_ret
    FROM dual;
    return v_ret;
END;

select * from strtokenizer('a,b,c',',')
ORA-00933: SQL command not properly ended

编辑:

  1. select * from table(strtokenizer('a,b,c',',')) 给出“ORA-30732:表不包含用户可见的列”。
  2. ORA-30732以函数所有者身份登录时消失了,但函数无法替换 ':string'||':delimiter' 与传入的值。我该如何纠正?当我没有以所有者身份登录时,如何运行函数?谢谢。

【问题讨论】:

  • 我手边没有 Oracle 实例,但您是否在以 SYS 身份登录时创建了函数和/或支持对象?
  • @OMG Ponies:哦,我以一个用户身份登录并为另一个模式创建了函数。这解决了 ORA-30732。谢谢。
  • for (2) 绑定变量不在单引号内求值,它们被视为任何其他字符串,在这种情况下,您不需要在变量名之前添加:;并通过授予用户执行权限,并可选择添加同义词。

标签: sql oracle function ora-00933


【解决方案1】:

假设函数编译成功,试试:

SELECT * 
  FROM TABLE(strtokenizer('a,b,c',','));

参考:

功能需要修正——使用:

CREATE OR REPLACE FUNCTION StrTokenizer (string IN VARCHAR2, 
                                         delimiter IN VARCHAR2)
RETURN key_value_table AS v_ret key_value_table
BEGIN
  SELECT CAST(MULTISET(SELECT LEVEL k, 
                              SUBSTR(STRING_TO_TOKENIZE, DECODE(LEVEL, 1, 1, INSTR(STRING_TO_TOKENIZE, DELIMITER, 1, LEVEL-1)+1), 
                              INSTR(STRING_TO_TOKENIZE, DELIMITER, 1, LEVEL) - DECODE( LEVEL, 1, 1, INSTR(STRING_TO_TOKENIZE, DELIMITER, 1, LEVEL-1)+1)) v
                         FROM (SELECT string || delimiter AS STRING_TO_TOKENIZE , 
                                      delimiter AS DELIMITER
                                 FROM DUAL)
                   CONNECT BY INSTR(STRING_TO_TOKENIZE, DELIMITER, 1, LEVEL)>0 
                     ORDER BY level ASC) AS key_value_table)
    INTO v_ret
    FROM DUAL;

  RETURN v_ret;

END;

【讨论】:

  • 它给了我“ORA-30732: table contains no user-visible columns”
  • @Martin:我手边没有 Oracle 实例,但是您是否在以 SYS 身份登录时创建了函数和/或支持对象?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多