oracle sql TO_CHAR函数在某些情况下添加了一个尾随空格

oracle sql TO_CHAR函数在某些情况下添加了一个尾随空格,sql,oracle,to-char,Sql,Oracle,To Char,我有一个带有数字列的表,我正试图用oracle sql函数将其格式化为\u char。根据列的显示方式,结果是否为尾随空白 SELECT '[',TO_CHAR(ABS(Balance), 'FM0000000000000000V00'),']', '[' || TO_CHAR(ABS(Balance),'FM0000000000000000V00') || ']' FROM Accounts 将得到以下结果: [;000000000749460366 ;];[00000000074

我有一个带有数字列的表,我正试图用oracle sql函数将其格式化为\u char。根据列的显示方式,结果是否为尾随空白

SELECT 
  '[',TO_CHAR(ABS(Balance), 'FM0000000000000000V00'),']',
  '[' || TO_CHAR(ABS(Balance),'FM0000000000000000V00') || ']'
FROM Accounts
将得到以下结果:

[;000000000749460366 ;];[000000000749460366]
[;000000008751094792 ;];[000000008751094792]
[;000000000000050696 ;];[000000000000050696]
[;000000000000000000 ;];[000000000000000000]
在这两种情况下,我都希望得到相同的结果,但我无法理解为什么会有差异。我为什么会有这些不同

非常感谢,, 皮埃尔·伊夫

SELECT 
  '[', lpad(ABS(Balance),18,0) ,']',
  '[' || lpad(ABS(Balance),18,0) || ']'
FROM Accounts 

这显示了相同的结果。

它没有向值添加尾随空格-如果检查长度,它仍然是18,如果是,则连接版本也会有空格。该列的元数据决定最大可能长度为19,如果原始余额值超过16位,这似乎是正确的:

set colsep ;
with accounts(balance) as (
  select 749460366 from dual
  union all select 1234567890123456 from dual
  union all select 12345678901234567 from dual
)
SELECT 
  '[',TO_CHAR(ABS(Balance), 'FM0000000000000000V00') as balance,']',
  '[',length(TO_CHAR(Balance, 'FM0000000000000000V00')) as length,']',
  '[' || TO_CHAR(ABS(Balance),'FM0000000000000000V00') || ']'
FROM Accounts;

';BALANCE            ;';';    LENGTH;';'['||TO_CHAR(ABS(BALA
-;-------------------;-;-;----------;-;---------------------
[;000000074946036600 ;];[;        18;];[000000074946036600] 
[;123456789012345600 ;];[;        18;];[123456789012345600] 
[;###################;];[;        19;];[###################]
17位数字的值不能以提供的格式显示,它替代了散列;但有趣的是,其中有19个,不管余额值实际上有多大

FM
修饰符抑制正值的前导空格;但是如果你有一个16位的负值,你仍然需要19位数字来显示它,因为减号会出现。您知道,由于调用了
ABS()
函数,该值不能为负值,但是
TO_CHAR()
函数不知道这一点,因此它仍然必须允许列宽中的减号

如果您真的从应用程序(例如通过JDBC)运行查询/转换,那么返回的字符串(小于17位,在
ABS()
之后)将是18个字符,并且不会有(不存在的)尾随空间

您的客户机(或者至少是SQL*Plus和SQL Developer)正在根据其认为的最宽值格式化列宽。您可以覆盖以下内容:

column balance format A18

with accounts(balance) as (
  select 749460366 from dual
  union all select 1234567890123456 from dual
  union all select 12345678901234567 from dual
  union all select 123456789012345678 from dual
)
SELECT 
  '[',TO_CHAR(ABS(Balance), 'FM0000000000000000V00') as balance,']',
  '[',length(TO_CHAR(Balance, 'FM0000000000000000V00')) as length,']',
  '[' || TO_CHAR(ABS(Balance),'FM0000000000000000V00') || ']'
FROM Accounts;

';BALANCE           ;';';    LENGTH;';'['||TO_CHAR(ABS(BALA
-;------------------;-;-;----------;-;---------------------
[;000000074946036600;];[;        18;];[000000074946036600] 
[;123456789012345600;];[;        18;];[123456789012345600] 
[;##################;];[;        19;];[###################]
 ;#                 ; ; ;          ; ;                     

[;##################;];[;        19;];[###################]
 ;#                 ; ; ;          ; ;                     
。。。这会使非空格消失,但如果/当原始值超过16位时,它会将额外的哈希值包装到下一行,则会更加混乱

您还可以显式地将结果强制转换为预期的长度:

clear columns

with accounts(balance) as (
  select 749460366 from dual
  union all select 1234567890123456 from dual
  union all select 12345678901234567 from dual
  union all select 123456789012345678 from dual
)
SELECT 
  '[',CAST(TO_CHAR(ABS(Balance), 'FM0000000000000000V00') as varchar2(18)) as balance,']',
  '[',length(TO_CHAR(Balance, 'FM0000000000000000V00')) as length,']',
  '[' || TO_CHAR(ABS(Balance),'FM0000000000000000V00') || ']'
FROM Accounts;

';BALANCE           ;';';    LENGTH;';'['||TO_CHAR(ABS(BALA
-;------------------;-;-;----------;-;---------------------
[;000000074946036600;];[;        18;];[000000074946036600] 
[;123456789012345600;];[;        18;];[123456789012345600] 
[;##################;];[;        19;];[###################]
[;##################;];[;        19;];[###################]