【问题标题】:pl/sql code to read data from filepl/sql 代码从文件中读取数据
【发布时间】:2014-10-31 06:35:15
【问题描述】:

我知道如何使用 utl_file 从文件中读取数据,但我遇到了以下数据的问题。我们不能假设哪个位置的数据会为空。我们该如何处理?

样本数据:apple|bat|cat|"dog | dog"||||eee||abc

预期输出:

col1:苹果
col2:bat
col3:猫
col4:狗狗
col5:
col6:
col7:
col8:eee
col9:
col10:abc

我尝试了下面的代码,但它没有处理空值

declare
list varchar2(3500) :='apple|bat|cat|"dog | dog"||||eee||abc';
pattern varchar2(20) := '(" [^"]*"|[^|]+)';
i number:=0;
j number;
f varchar2(3500);
 c sys_refcursor;
begin
dbms_output.put_line('Raw list: ' || list);
 open c for
             select  level as col,
                 trim(regexp_substr(replace(list,'|','|'), pattern, 1, rownum))split  
             from dual
             connect by level <= length(regexp_replace(list, pattern))  + 1;
        loop
            fetch c into j, f;
            exit when c%notfound;
            dbms_output.put_line('Column ' || i || ': ' || replace(f, '"'));
            i:=i+1;
        end loop;
        close c;

end;

我的输出低于预期,但我需要预期的输出。

原始列表:apple|bat|cat|"dog|dog"||||eee||abc
第 0 列:苹果
第 1 栏:蝙蝠
第 2 栏:猫
第 3 栏:狗
第 4 栏:狗
第 5 栏:eee
第 6 栏:abc
第 7 栏:
第 8 栏:
第 9 栏:
第 10 栏:

【问题讨论】:

  • 我可以想到几种方法来解决这个问题:1) 状态机,2) 正则表达式,3) INSTR 和 SUBSTR。祝你好运。

标签: plsql utl-file


【解决方案1】:

我不会为此使用正则表达式。

相反,我会使用普通的字符串操作函数来拆分字符串。例如:

declare
    list varchar2(3500) := 'apple|bat|cat|"dog | dog"||||eee||abc';

    next_pipe_pos       integer;
    close_quote_pos     integer;
    column_start_pos    integer;
    column_num          integer;
    column_text         varchar2(4000);
begin
    column_start_pos := 1;
    column_num := 1;

    -- Appending a | character allows us to assume that all columns have a
    -- pipe following them and avoids any special-case handling for the last
    -- column.
    list := list || '|';

    while column_start_pos <= length(list)
    loop
        if substr(list, column_start_pos, 1) = '"' then
            close_quote_pos := instr(list, '"|', column_start_pos + 1);
            if close_quote_pos = 0 then
                -- Mismatched quotes.
                raise no_data_found;
            end if;

            column_text := substr(list, column_start_pos + 1, close_quote_pos - column_start_pos - 1);
            column_start_pos := close_quote_pos + 2;
        else
            next_pipe_pos := instr(list, '|', column_start_pos);
            exit when next_pipe_pos = 0;
            column_text := substr(list, column_start_pos, next_pipe_pos - column_start_pos);
            column_start_pos := next_pipe_pos + 1;
        end if;

        dbms_output.put_line('Column ' || column_num || ': ' || column_text);

        column_num := column_num + 1;        
    end loop;
end;

它的代码更多,但可以说它比您使用的正则表达式更隐蔽。

运行的输出:

Column 1: apple
Column 2: bat
Column 3: cat
Column 4: dog | dog
Column 5:
Column 6:
Column 7:
Column 8: eee
Column 9:
Column 10: abc

【讨论】:

  • 嗨卢克伍德沃德,非常感谢您的解决方案。
猜你喜欢
  • 2016-11-16
  • 2010-09-18
  • 2016-03-17
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 2020-09-21
  • 2021-12-30
  • 1970-01-01
相关资源
最近更新 更多