【问题标题】:comma separated list invalid near.. with comma_to_table逗号分隔的列表在附近无效.. 带有 comma_to_table
【发布时间】:2017-11-27 22:46:30
【问题描述】:

我正在尝试使用逗号分隔的字符串并将每个值作为新行插入到表中。我从 Lalit Kumar B 中获取了以下示例,并修改了数据以类似于我的数据的样子。

DECLARE
    L_INPUT VARCHAR2(4000) := '522,33-23,125,658,25,12-500';
    L_COUNT BINARY_INTEGER;
    L_ARRAY DBMS_UTILITY.LNAME_ARRAY;
BEGIN
    DBMS_UTILITY.COMMA_TO_TABLE(LIST => REGEXP_REPLACE(L_INPUT, '(^|,)', '\1x'), TABLEN => L_COUNT, TAB => L_ARRAY);
    DBMS_OUTPUT.PUT_LINE(L_COUNT);
    FOR I IN 1 .. L_COUNT
    LOOP
        DBMS_OUTPUT.PUT_LINE('Element ' || TO_CHAR(I) || ' of array contains: ' || SUBSTR(L_ARRAY(I), 2));
        INSERT INTO TEST22 VALUES
        (SUBSTR(L_ARRAY(I), 2)
        );
        COMMIT;
    END LOOP;
END;

我收到以下 oracle 错误:ORA-20001: comma-separated list invalid near 33-23

如何处理“33-23”形式的数据?如果我从我的数据中取出“-”,上述将按需要运行。这并不理想,因为我的一些数据中会包含“-”并且无法删除。

【问题讨论】:

  • 你认为dbms_utility.comma_to_table 的过程是做什么的?它适用于数据库标识符(格式为schema.table.column@link 及其变体)。现在,您可能会滥用它来拆分逗号分隔的字符串,正如您正在尝试的那样 - 会产生不可预测的结果。标识符中不允许使用破折号。无论如何,如果您需要拆分逗号分隔的字符串,请这样说;有很多方法,但comma_to_table 过程不是其中之一。
  • 用下划线替换它们
  • 等等... Lalit 是否将其显示为一种拆分字符串的方法?还是他用它来做别的事情?如果他显示它用于拆分字符串,请提供链接;他应该从有效方法列表中删除此方法。
  • @Used_By_Already 我无法修改数据。数据代表我的真实数据的样子,因此我无法修改数据,只需插入即可。
  • @mathguy 是的,Lalit 将其显示为“将逗号分隔的字符串值插入表中”的一种方式,这正是我需要做的。这是链接.. lalitkumarb.wordpress.com/2014/03/07/…

标签: oracle plsql oracle11g


【解决方案1】:

一种方法是使用 CONNECT BY 有效地循环遍历字符串元素。如果您只运行查询,您将看到它是如何工作的。正则表达式允许出现 NULL 列表元素。

insert into TEST(col_a) 
select regexp_substr('522,33-23,125,658,25,12-500', '(.*?)(,|$)', 1, level, null, 1)
from dual
connect by level <= regexp_count('522,33-23,125,658,25,12-500', ',')+1

【讨论】:

  • 感谢您为我指明了正确的方向。这就是我需要的。我不得不稍作修改,因为我有一个更大的插入列表,但这正是我想要的。再次感谢您的帮助
【解决方案2】:

我对 DBMS_UTILITY.COMMA_TO_TABLE 有同样的问题。它有一些数字字符串的错误。我尝试了一些方法,最后写了这个函数而不是它。

CREATE OR REPLACE PACKAGE UTILITY_METHODS IS

TYPE STRING_TAB IS TABLE OF VARCHAR2(512) INDEX BY BINARY_INTEGER;

FUNCTION SPLIT_STR(  P_STRING        IN VARCHAR2
                   , P_SEPRATOR_CHAR IN VARCHAR2)
RETURN STRING_TAB;

END UTILITY_METHODS;

CREATE OR REPLACE PACKAGE BODY UTILITY_METHODS IS

FUNCTION SPLIT_STR(  P_STRING        IN VARCHAR2
                   , P_SEPRATOR_CHAR IN VARCHAR2)
RETURN STRING_TAB
IS
  STR_TAB STRING_TAB;
  L_SEP_CHAR VARCHAR2(1) := NVL(P_SEPRATOR_CHAR, ',');
  L_PATERN VARCHAR2(10)  := '[^' || L_SEP_CHAR || ']+';
BEGIN
  IF P_STRING IS NULL THEN
    RETURN STR_TAB;
  END IF;

  FOR RC IN (
              WITH L_LINE(STR) AS    
              (
                SELECT P_STRING
                FROM DUAL
              )
              SELECT REGEXP_SUBSTR(STR, L_PATERN, 1, LEVEL) SP_STR
              FROM L_LINE
              CONNECT BY LEVEL <= REGEXP_COUNT(STR, L_SEP_CHAR) + 1
            )
  LOOP
    STR_TAB(STR_TAB.COUNT) := RC.SP_STR;  
  END LOOP;

  RETURN STR_TAB;
END;  

END UTILITY_METHODS;

如果您想在 select 语句中使用此函数,您可以将函数的返回类型更改为 PIPE_LINED。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    相关资源
    最近更新 更多