Oracle 拆分字符串并迭代存储过程中的每个值

Oracle 拆分字符串并迭代存储过程中的每个值,oracle,stored-procedures,oracle11g,tokenize,Oracle,Stored Procedures,Oracle11g,Tokenize,我在Oracle中有一个要求,我必须将逗号分隔的国家代码字符串传递给Oracle存储过程 在存储过程中,我希望以逗号分隔字符串,并对每个国家/地区代码进行迭代 我想要一个类似如下的SP: PROCEDURE Get_Query ( v_company IN VARCHAR2, ) IS sqlstr VARCHAR2(32767); BEGIN /* split the v_company on comma (e.g. IN,US,...etc) iterate for each coun

我在Oracle中有一个要求,我必须将逗号分隔的国家代码字符串传递给Oracle存储过程

在存储过程中,我希望以逗号分隔字符串,并对每个国家/地区代码进行迭代

我想要一个类似如下的SP:

PROCEDURE Get_Query
(
  v_company IN VARCHAR2,

) IS
sqlstr VARCHAR2(32767);
BEGIN
/*
split the v_company on comma (e.g. IN,US,...etc)
iterate for each country code  

*/
END;
你可以用

DBMS_实用程序包提供各种实用程序子程序。其中一个有用的实用程序是COMMA_TO_TABLE过程,它将逗号分隔的名称列表转换为PL/SQL名称表

比如说,

SQL> set serveroutput on;
SQL> DECLARE
  2    l_tablen BINARY_INTEGER;
  3    l_tab DBMS_UTILITY.uncl_array;
  4    CURSOR cur
  5    IS
  6      SELECT 'word1, word2, word3, word4, word5, word6' val FROM dual;
  7    rec cur%rowtype;
  8  BEGIN
  9    OPEN cur;
 10    LOOP
 11      FETCH cur INTO rec;
 12      EXIT
 13    WHEN cur%notfound;
 14      DBMS_UTILITY.comma_to_table (
 15      list => rec.val, tablen => l_tablen, tab => l_tab);
 16      FOR i IN 1 .. l_tablen
 17      LOOP
 18        DBMS_OUTPUT.put_line(i || ' : ' || trim(l_tab(i)));
 19      END LOOP;
 20    END LOOP;
 21    CLOSE cur;
 22  END;
 23  /
1 : word1
2 : word2
3 : word3
4 : word4
5 : word5
6 : word6

PL/SQL procedure successfully completed.

SQL>
正如@ruudvan所指出的更新,在使用逗号到表格时有一些限制,比如,如果您将关键字作为分隔字符串(如IS、As等)使用,它将不起作用

要克服逗号到表的限制,还有许多其他方法,请参阅

例如,您可以使用正则表达式,如下所示:

测试用例

让我们检查一下:

SQL> set serveroutput on
SQL> EXEC get_query('COMP1,COMP2,COMP3,COMP4');
Company code no.1 = COMP1
Company code no.2 = COMP2
Company code no.3 = COMP3
Company code no.4 = COMP4

PL/SQL procedure successfully completed.

SQL>

正则表达式的使用将输入字符串转换为令牌流,这些令牌流可以像任何其他SELECT语句的结果集一样进行处理

PROCEDURE Get_Query
(
  v_company IN VARCHAR2,

) IS
    sqlstr VARCHAR2(32767);
BEGIN

    for rec in (select distinct regexp_substr(v_company, '[^,]+', 1, level) as ctry
    from dual
    connect by level <= regexp_count (v_company, '[,]')  +1
   loop
        do_something ( rec.ctry );

    end loop;
END;

我认为您应该在这里使用regexp\u substr方法,而不是逗号到表。无论何时,只要你推荐某人使用逗号,我觉得你也应该告诉他们逗号的局限性。汤姆·凯特总结了一下。即使在这个特定的国家代码示例中,它也可能不会给您提供正确的结果,因为OP可以有像AS和IS这样的国家代码,这是保留字,逗号\u到\u表将无法处理它们。@ruudvan内置包当然有限制。这就是我提供文章链接的原因,我在这里演示了各种方法。我会让OP回来问他是否需要更多的帮助。如果我必须深入细节,在这里提供每一个微观细节,那就像是在写一本书。无论如何,谢谢你的评论。如果OP带着更多的担忧回来,我将非常乐意帮助他。你有足够的代表了解StackOverflow的工作原理。我们应该在这个网站上提供有效的答案。提供一个低于标准的解决方案——正如@ruudvan指出的,逗号到表格就是这样——再加上你博客的链接是不够好的。@APC和ruudvan,够公平的家伙们。添加了一个完整的工作解决方案。谢谢你推我-这是一个如此普遍的请求,请尝试谷歌搜索、stackoverflow oracle解析csv字符串。这方面的文件并不缺乏。
PROCEDURE Get_Query
(
  v_company IN VARCHAR2,

) IS
    sqlstr VARCHAR2(32767);
BEGIN

    for rec in (select distinct regexp_substr(v_company, '[^,]+', 1, level) as ctry
    from dual
    connect by level <= regexp_count (v_company, '[,]')  +1
   loop
        do_something ( rec.ctry );

    end loop;
END;