2009-03-17 7 views
4

Quelle est la meilleure pratique pour justifier un numéro numérique dans TSQL?Meilleure pratique pour justifier un numéro numérique dans TSQL

Je dois formater un fichier d'extraction de longueur fixe et avoir besoin d'avoir les champs numériques justifiés à droite. (J'utilise SQL Server 2005)

J'ai trouvé this, ce qui semble assez simple.

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

Voici la déclaration complète Sélectionnez

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) 

Je pose cette question parce que je trouve cette ligne de code au travail, qui apparaît Insanely complexe (Il supprime également la décimale et zéro remplissage)

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)) 

Mise à jour:

L'idée de Daniel Pratt d'utiliser une fonction m'a fait regarder SQL# (que nous possédons). Il a une fonction appelée PadLeft, qui étonnamment avait les mêmes paramètres et fonctionnalités que la fonction fn_PadRight de Daniel Pratt définie dans sa réponse ci-dessous.

Voici comment utiliser la fonction 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,' ') 

Il peut prendre les deux nombres et les chaînes.

+1

est-il une raison que vous êtes désireux de faire cette justification directement dans votre code tsql et non dans la zone de sortie (par exemple un site Web, des services de rapports, etc. .?) Essayer de marteler la disposition dans le code de tsql lui-même est un gros WTF attendant pour arriver, à mon humble avis. – TheTXI

+0

@TheTXI: Lisez plus attentivement. Il n'y a pas de "zone de sortie" autre qu'un extrait * fichier *. Comment un fichier d'extraction effectue-t-il le formatage des données? –

+0

La question originale a dit que c'était pour un fichier "extrait". En tant que tel, il ne semble pas qu'il mélange les données et la présentation. –

Répondre

1

La seule chose que je peux suggérer pour aider à la "complexité insensée" est de l'encapsuler dans une ou plusieurs fonctions. Voici une version quelque peu modifiée de quelque chose que nous utilisons:

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 
0

La meilleure pratique en général serait de faire en sorte que la base de données renvoie des données et que la couche de présentation formate les données. Vous ne devriez pas formater les données dans la base de données.


Maintenant, ce que le commentaire indique - vous créez un fichier d'extraction. Je me demande toujours comment vous allez obtenir les données de SQL Server et dans le fichier. SQL Server ne crée-t-il pas le fichier disque via une requête?

Je recommande toujours de séparer les données de leur présentation, même si cette présentation est un fichier de longueur fixe. C'est le genre de chose que nous faisions «dans le bon vieux temps», mais que nous devrions éviter aujourd'hui, maintenant que nous avons des ordinateurs assez rapides pour faire face à des choses comme la séparation des préoccupations.

+0

Merci pour votre réponse. Je dois formater les données dans la base de données. –

+1

Bien que ce fut ma première pensée du post sujet, il a spécifiquement dit qu'il produisait un fichier * extrait * de longueur fixe. –

1

Vous n'allez pas comme ma réponse, mais la meilleure pratique est de le faire ailleurs que dans SQL. SQL est destiné à stocker récupérer et traiter les données ne pas le visualiser. Ne pas le formater pour l'affichage. Vous seriez beaucoup mieux à mon humble avis ayant une application console qui tire les données puis génère le fichier.

Mais avec cela dit quand je l'ai fait auparavant, je l'ai fait comme ceci:

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

espaces hardcoding si méchant, cela vaut sans doute une pause pour un grand nombre, mais là encore, si votre génération d'un fichier fixe votre va générer des déchets pour un grand de toute façon nombre

Modifier

Ken j'ai lu les ops poste et oui, il formate les données dans un fichier largeur fixe. Le fait est que vous devriez faire la mise en forme dans un niveau d'application, pas en SQL.Oui, il n'y a personne qui regarde les données visuellement, mais je suppose que j'ai l'impression que vous continuez à formater les données, nous divisons probablement les poils.

+0

@Josh: Lisez le post avant de répondre. Il n'y a pas de "visualisation" ou d'affichage ici - l'OP produit un fichier d'extraction *. S'il vous plaît expliquer comment un fichier texte fait la présentation ou le formatage des données. –

+0

Je doute que le fichier soit créé par l'application, la plupart de ces choses sont faites par des travaux ou des pacakages de SSIS ou semblable et ne se rapproche même jamais de l'application. – HLGEM

Questions connexes