我需要帮助生成固定宽度的文件,其中每行的长度相同。我知道我必须将每个字段都转换为固定长度的字符字段。字段的大小应该是源表中字段的最大大小。但是,只是无法使用以下查询生成文件 -
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)
答案 0 :(得分:0)
您正在将列值转换为char(n)
,这会将较短的字符串和数字(隐式转换为字符串)填充到 n 字符,并截断较长的值。 (这比使用varchar2(n)
更好,因为数字越长就会出错,并且不会对更短的字符串产生任何影响。
你会遇到空值问题,因为cast(null as char(n))
- 或其他任何东西 - 仍然是空的,而不是像你期望的那样 n 空格。对于任何列,这可能都是一个问题,尤其是对于您的案例表达式。
如果任何列可以为null,则可以使用nvl
或coalesce
将它们视为单个空格,然后演员也将填充这些列:
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。希望这会帮助你。