在SQL中右对齐数值的最佳实践

时间:2009-03-17 20:12:02

标签: sql sql-server tsql

在TSQL中对数字进行右对齐的最佳做法是什么?

我必须格式化固定长度的提取文件,并且需要将数字字段右对齐。 (我使用的是SQL Server 2005)

我找到了this,这看起来非常简单。

right('            '+convert(varchar(20),a.num),12)

这是完整的Select语句

select
    a.num,
    fixed_number =
        right('            '+convert(varchar(20),a.num),12)
from
    (
    --Test Data
    select num = 2400.00    union all
    select num = 385.00 union all
    select num = 123454.34
    ) a

Results:

num        fixed_number 
---------- ------------ 
2400.00         2400.00
385.00           385.00
123454.34     123454.34

(3 row(s) affected)

我问这个问题,因为我发现这行代码在工作,看起来INSANELY复杂(它也删除小数和零填充)

CAST(REPLACE(REPLICATE('0', 12 - LEN(REPLACE(CAST(CONVERT(DECIMAL(10,2),@DD8DBAMT) AS VARCHAR),'.',''))) 
+ CAST(CONVERT(DECIMAL(10,2),@DD8DBAMT) AS VARCHAR),'.','') AS VARCHAR(12))

更新

Daniel Pratt使用函数的想法让我看到SQL#(我们拥有)。它有一个名为PadLeft的函数,令人惊讶的是它具有与Daniel Pratt在下面的答案中定义的fn_PadRight函数相同的参数和功能。

以下是如何使用SQL#函数:

DECLARE @F6D2 AS DECIMAL(8,2)
SET @F6D2 = 0
SQL#.String_PadLeft(@F6D2,9,' ')
SQL#.String_PadLeft(123.400,9,' ')
SQL#.String_PadLeft('abc',9,' ')

它可以同时包含数字和字符串。

3 个答案:

答案 0 :(得分:1)

你不会像我的回答那样,但最好的做法是在SQL以外的地方做这个。 SQL旨在存储检索和处理数据,而不是将其可视化。不格式化显示。你会好得多的恕我直言,有一个控制台应用程序,可以提取数据,然后生成文件。

但是,当我之前说过这样做时,我这样做了:

declare @num int
set @num=1555
select replicate(' ',20-len(cast(@num as varchar))) + cast(@num as varchar)

硬编码空间如此讨厌,这可能会破坏一个庞大的数字,但如果你生成一个固定的文件,你会生成垃圾无论如何大量

修改

Ken我确实阅读过ops帖子,是的,他正在将数据格式化为固定宽度的文件。关键是您应该在应用程序层中进行格式化,而不是在SQL中进行格式化。是的,没有人在视觉上看数据,但我想我觉得你还在制作数据,我们正在分裂头发。

答案 1 :(得分:1)

我唯一可以建议帮助解决“疯狂的复杂性”的问题是将其封装在一个或多个函数中。这是我们正在使用的某种修改版本:

CREATE FUNCTION [dbo].[fn_PadRight]
(
    @Value nvarchar(4000)
    ,@NewLength int
    ,@PadChar nchar(1) = ' '
) RETURNS nvarchar(4000)
AS
BEGIN
    DECLARE @ValueLength int
    SET @ValueLength = LEN(@Value)

    IF (@NewLength > @ValueLength) BEGIN
        SET @Value = @Value + REPLICATE(@PadChar, @NewLength - @ValueLength)
    END

    RETURN @Value
END
GO

CREATE FUNCTION [dbo].[fn_FormatAmountDE]
(
    @Value money
) RETURNS nvarchar(4000)
AS
BEGIN
    RETURN [dbo].[fn_PadRight](REPLACE(CAST(@Value AS varchar), '.', ''), 12, '0')
END
GO

答案 2 :(得分:0)

一般来说,最佳做法是让数据库返回数据,并使表示层格式化数据。您不应该格式化数据库中的数据。


我现在评论指出 - 你正在创建一个提取文件。我仍然想知道你将如何从SQL Server和文件中获取数据。当然SQL Server没有通过查询创建磁盘文件?

我仍然建议将数据与其演示文稿分开,即使该演示文稿是固定长度的文件。这是我们以前做过的“在过去的好日子里”,但今天应该避免,现在我们有足够快的计算机处理诸如关注点分离之类的事情。