【问题标题】:Oracle UTL_FILE - multiple rows in excel for a single cellOracle UTL_FILE - 单个单元格的 excel 中的多行
【发布时间】:2012-12-05 13:18:11
【问题描述】:

我需要在使用 PL/SQL 的 UTL_FILE 包生成的 csv 文件中显示以下内容。

标题1 标题2 标题3 ABCDE 123 987641213 xxx街 年年了

对于“Heading1”中的每个值,我从特定表中获取 3 行地址。 在输出的 csv 文件中,我需要在单个单元格中显示地址,数据由新行分隔。

我尝试使用游标并使用 chr(10)、chr(12)、chr(15) 附加数据,但没有成功。

请帮助我获得输出。

【问题讨论】:

    标签: oracle csv plsql utl-file


    【解决方案1】:

    您必须引用具有回车符的字段

    heading1,headiing2,heading3
    abcde,123,"1 street
    town
    90210"
    abcde,124,"13 street
    town
    43245"
    

    【讨论】:

    • 嗨 Dazzal,我尝试使用回车 ASCII 值。我正在将 UTL_FILE 输出写入带有逗号分隔列表的 csv 文件。但是我将这些特定的回车作为特殊字符,例如每行之间的框。它们也显示在同一行。
    • 你用什么字符序列来回车?它应该是 chr(13)||chr(10)。
    【解决方案2】:

    DazzaL 建议的内容应该可行,但如果您无法更改您的情况下的输入文件,您可以使用以下代码:

    declare
        v_line varchar2(2000);
        v_c1   varchar2(10);
        v_c2   varchar2(10);
        v_c3   varchar2(1980);
        nb_line_per_record integer := 3;
        v_line_in_record   integer;
        v_seperator varchar2(1) := ',';
        v_file UTL_FILE.FILE_TYPE;
    begin
        v_file := utl_file.FOPEN(your_directory, 'your_file','r');
        v_line_in_record := 0;
        --we skip the first line
        UTL_FILE.GET_LINE(v_file, v_line);
        loop
            v_line_in_record := v_line_in_record + 1; 
            begin
                UTL_FILE.GET_LINE(v_file, v_line);
            EXCEPTION
                WHEN no_data_found THEN
                    exit;
            END;
            --first line of record we cut by v_seperator
            if v_line_in_record = 1 then
               v_c1 := substr(v_line,1,instr(v_line,v_seperator,1,1)-1);
               v_c2 := substr(v_line,instr(v_line,v_seperator,1,1)+1,
                              instr(v_line,v_seperator,1,2)-                                
                              instr(v_line,v_seperator,1,1)-1);
               v_c3 := substr(v_line,instr(v_line,v_seperator,1,2)+1) 
                              || char(10);--if you want new line in adresse 
            else
                --not first line we concatanate to adress with new line
                v_c3 := v_c3 || v_line ||
                        case when v_line_in_record = 2 then char(10) else '' end; 
            end if;
            if v_line_in_record = 3 then
                v_line_in_record := 0;
                --do something with your record 
                insert into yourtable values (v_c1,v_c2,v_c3);
            end if;
        end loop;
        UTL_FILE.FCLOSE(v_file);
        COMMIT;
    end;
    

    但这只有在您绝对确定每条记录都是 3 行时才有效。如果我是你,我会在每条记录后添加一个记录分隔符并使用SQLLOADER 将此文件加载到表中。您可以使用 SQLLOADER 定义记录分隔符。这是一个使用 & 作为记录分隔符的示例 ctl

    options (skip=1) 
      load data 
      infile "yourfile" "str '&'" 
      truncate into table your_table 
      fields terminated by "," 
      trailing nullcols 
      (heading1, heading2, heading3)
    

    如果您使用记录分隔符,您甚至可以在文件上创建External Table

    【讨论】:

    • 您好 Bulent,感谢您的精彩询问。但问题是 char(10) 会使 3row 输出的第 2 行显示在 excel 的下一行中...我需要显示这 3 行,就像我们在 excel 中使用 ALT+ENTER 输入的方式一样单个单元格内的多行数据....基本上,应该是 ALT+ENTER ALT+ENTER 这将允许所有数据出现在单个单元格中。
    猜你喜欢
    • 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
    相关资源
    最近更新 更多