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

问题描述 投票:0回答:2

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

    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)
sql oracle plsql
2个回答
0
投票

您将列值转换为

char(n)
,这会将较短的字符串和数字(隐式转换为字符串)填充为 n 字符,并截断较长的值。 (这比使用
varchar2(n)
更好,后者对于较长的数字会出错,并且对于较短的字符串不会产生任何影响)。

但是,您将遇到空值问题,因为

cast(null as char(n))
- 或其他任何内容 - 仍然为空,而不是您可能期望的 n 空格。这对于您的任何列都可能是个问题,尤其是对于您的 case 表达式。

如果任何列可以为空,您可以使用

nvl
coalesce
将它们视为单个空格,然后强制转换也会填充这些列:

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

除了铸造之外,您还可以使用

rpad()

rpad(coalesce(First_name, ' '), 20, ' ')

对于 case 表达式,您可以使

else
子句计算为单个空格而不是 null,但您还需要将强制转换应用于整个 case 表达式,而不是将其放在一个
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
,或者假脱机
set trimspool off
,SQL*Plus 会这样做;这可能就是 BobC 所指的),但是如果您真正想要创建的是固定长度字段,那么这并没有真正的帮助,它累积起来也会为您提供固定长度的记录 - 如果您没有固定长度的字段,则无法解释数据无论如何。


-1
投票

我以前也遇到过类似的问题。 Anton Scheffer 有一个名为 as_xlsx 的包,它解决了我的问题。查看有关此问题的问题:使用 PL/SQL 创建 Excel 文件 (.xlsx)。希望这对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.