从SQL查询生成固定宽度的平面格式输出文件

时间:2017-02-20 19:09:55

标签: sql oracle plsql

我需要帮助生成固定宽度的文件,其中每行的长度相同。我知道我必须将每个字段都转换为固定长度的字符字段。字段的大小应该是源表中字段的最大大小。但是,只是无法使用以下查询生成文件 -

    Select cast(x.account_id as char(10)) ||
           cast(birth_month as char(2)) ||
           cast(birth_year as char(4))|| 
           TO_CHAR(LastVisittDate,'yyyymmdd') ||'    '||
           max(case when email_Rank = 1 then cast(email_address as char(100)) else null end) ||chr(13) as ConstitRow

 from INTERS XR
               inner join INTERS_REL RX on XR.account_id = RX.account_id and RX.sts <> 'D'

       where 
               RX.account_id in (deleted - long list of account IDs)

2 个答案:

答案 0 :(得分:0)

您正在将列值转换为char(n),这会将较短的字符串和数字(​​隐式转换为字符串)填充到 n 字符,并截断较长的值。 (这比使用varchar2(n)更好,因为数字越长就会出错,并且不会对更短的字符串产生任何影响。

你会遇到空值问题,因为cast(null as char(n)) - 或其他任何东西 - 仍然是空的,而不是像你期望的那样 n 空格。对于任何列,这可能都是一个问题,尤其是对于您的案例表达式。

如果任何列可以为null,则可以使用nvlcoalesce将它们视为单个空格,然后演员也将填充这些列:

cast(coalesce(First_name, ' ') as char(20))

您也可以使用rpad()

,而不是投射
rpad(coalesce(First_name, ' '), 20, ' ')

对于case表达式,您可以将else子句求值为单个空格而不是null,但是您还需要将强制转换应用于整个案例表达式,而不是将其置于一个when中科;所以不要这样:

max(case when email_Rank = 1 then cast(email_address as char(100)) else null end)

你会这样做:

cast(max(case when email_Rank = 1 then email_address else ' ' end) as char(100))

或者如果您愿意:

cast(coalesce(max(case when email_Rank = 1 then email_address end), ' ') as char(100))

您的客户端可能一直在将整个字符串填充到相同的长度(如果您有set trimout off,SQL * Plus会执行此操作,或者假脱机set trimspool off;这可能是BobC的内容参考),但如果您真正想要创建的是固定长度的字段,那么这并不是真的有用,它累积地会给您一个固定长度的记录 - 如果你没有固定长度的字段,无论如何也无法解释数据。

答案 1 :(得分:-1)

之前我遇到过类似的问题。 Anton Scheffer有一个名为as_xlsx的软件包,它解决了我的问题。查看有关此内容的问题:Create an Excel File (.xlsx) using PL/SQL。希望这会帮助你。