web-dev-qa-db-fra.com

Remplissez une chaîne avec des zéros non significatifs de manière à ce qu'il ait 3 caractères dans SQL Server 2008

J'ai une chaîne pouvant contenir jusqu'à 3 caractères lorsqu'elle a été créée pour la première fois dans SQL Server 2008 R2.

Je voudrais le compléter avec des zéros non significatifs. Ainsi, si sa valeur initiale était "1", la nouvelle valeur serait "001". Ou, si sa valeur d'origine était "23", la nouvelle valeur est "023". Ou si sa valeur d'origine est '124', la nouvelle valeur est identique à la valeur d'origine.

J'utilise SQL Server 2008 R2. Comment ferais-je cela avec T-SQL?

301
Sunil

Si le champ est déjà une chaîne, cela fonctionnera

 SELECT RIGHT('000'+ISNULL(field,''),3)

Si vous voulez que les nulls apparaissent en '000'

Ce pourrait être un entier - alors vous voudriez 

 SELECT RIGHT('000'+CAST(field AS VARCHAR(3)),3)

Comme l'exige la question, cette réponse ne fonctionne que si la longueur <= 3; si vous voulez quelque chose de plus grand, vous devez modifier la constante chaîne et les deux constantes entières par la largeur requise. p.ex. '0000' and VARCHAR(4)),4

540
Hogan

Bien que la question concerne SQL Server 2008 R2, au cas où quelqu'un le lirait à partir de la version 2012 ou ultérieure, cela est devenu beaucoup plus facile grâce à l'utilisation de FORMAT .

Vous pouvez soit passer un chaîne de format numérique standard _ ou un chaîne de format numérique personnalisée _ comme argument de format (remercier Vadim Ovchinnikov pour cet indice).

Pour cette question par exemple un code comme

DECLARE @myInt INT = 1;
-- One way using a standard numeric format string
PRINT FORMAT(@myInt,'D3');
-- Other way using a custom numeric format string
PRINT FORMAT(@myInt,'00#');

les sorties

001
001
101
Géza

La méthode sûre:

SELECT REPLACE(STR(n,3),' ','0')

Cela a l’avantage de renvoyer la chaîne '***' pour n <0 ou n> 999, ce qui est un indicateur de Nice et évident des entrées hors limites. Les autres méthodes répertoriées ici échoueront en silence en tronquant l'entrée en une sous-chaîne de 3 caractères.

77
Anon

Voici une technique plus générale pour gaucher à la largeur souhaitée:

declare @x     int     = 123 -- value to be padded
declare @width int     = 25  -- desired width
declare @pad   char(1) = '0' -- pad character

select right_justified = replicate(
                           @pad ,
                           @width-len(convert(varchar(100),@x))
                           )
                       + convert(varchar(100),@x)

Cependant, si vous avez affaire à des valeurs négatives et à un remplissage avec des zéros non significatifs, ni cela, ni aucune autre technique suggérée ne fonctionneront. Vous obtiendrez quelque chose qui ressemble à ceci:

00-123

[Probablement pas ce que tu voulais]

Alors… vous devrez sauter à travers quelques obstacles supplémentaires Voici une approche qui formatera correctement les nombres négatifs:

declare @x     float   = -1.234
declare @width int     = 20
declare @pad   char(1) = '0'

select right_justified = stuff(
         convert(varchar(99),@x) ,                            -- source string (converted from numeric value)
         case when @x < 0 then 2 else 1 end ,                 -- insert position
         0 ,                                                  -- count of characters to remove from source string
         replicate(@pad,@width-len(convert(varchar(99),@x)) ) -- text to be inserted
         )

Il convient de noter que les appels convert() doivent spécifier un [n]varchar de longueur suffisante pour conserver le résultat converti avec une troncature.

28
Nicholas Carey

Voici une variante de la réponse de Hogan que j'utilise dans SQL Server Express 2012:

SELECT RIGHT(CONCAT('000', field), 3)

Au lieu de m'inquiéter de savoir si le champ est une chaîne ou non, je l'ai simplement CONCAT, car il produira une chaîne de toute façon. De plus, si le champ peut être un NULL, l'utilisation de ISNULL peut être nécessaire pour éviter que la fonction obtienne des résultats NULL.

SELECT RIGHT(CONCAT('000', ISNULL(field,'')), 3)
22
jahu

J'ai toujours trouvé la méthode suivante très utile.

REPLICATE('0', 5 - LEN(Job.Number)) + CAST(Job.Number AS varchar) as 'NumberFull'
15
Bill

Utilisez cette fonction qui convient à toutes les situations.

CREATE FUNCTION dbo.fnNumPadLeft (@input INT, @pad tinyint)
RETURNS VARCHAR(250)
AS BEGIN
    DECLARE @NumStr VARCHAR(250)

    SET @NumStr = LTRIM(@input)

    IF(@pad > LEN(@NumStr))
        SET @NumStr = REPLICATE('0', @Pad - LEN(@NumStr)) + @NumStr;

    RETURN @NumStr;
END

Échantillon de sortie

SELECT [dbo].[fnNumPadLeft] (2016,10) -- returns 0000002016
SELECT [dbo].[fnNumPadLeft] (2016,5) -- returns 02016
SELECT [dbo].[fnNumPadLeft] (2016,2) -- returns 2016
SELECT [dbo].[fnNumPadLeft] (2016,0) -- returns 2016 
11
Salar

Pour ceux qui souhaitent mettre à jour leurs données existantes, voici la requête:

update SomeEventTable set eventTime=RIGHT('00000'+ISNULL(eventTime, ''),5)
5
Alan B. Dee

Pour les entiers, vous pouvez utiliser la conversion implicite d’int en varchar:

SELECT RIGHT(1000 + field, 3)
3
Konstantin

J'avais un problème similaire avec la colonne entière comme entrée lorsque j'avais besoin d'une sortie varchar (ou chaîne) de taille fixe. Par exemple, 1 à '01', 12 à '12'. Ce code fonctionne:

SELECT RIGHT(CONCAT('00',field::text),2)

Si l'entrée est également une colonne de varchar, vous pouvez éviter la pièce moulée. 

1
user3183867

J'ai écrit ceci parce que j'avais des exigences pour une longueur spécifique (9) . Remplit la gauche avec @pattern SEULEMENT lorsque l'entrée a besoin d'être complétée . Devrait toujours renvoyer la longueur définie dans @pattern.

declare @charInput as char(50) = 'input'

--always handle NULL :)
set @charInput = isnull(@charInput,'')

declare @actualLength as int = len(@charInput)

declare @pattern as char(50) = '123456789'
declare @prefLength as int = len(@pattern)

if @prefLength > @actualLength
    select Left(Left(@pattern, @prefLength-@actualLength) + @charInput, @prefLength)
else
    select @charInput

Retourne 1234input

1
nicky

Simple est que

Comme:

DECLARE @DUENO BIGINT
SET @DUENO=5

SELECT 'ND'+STUFF('000000',6-LEN(RTRIM(@DueNo))+1,LEN(RTRIM(@DueNo)),RTRIM(@DueNo)) DUENO
1
DEBASIS PAUL

Je connais son vieux ticket, je pensais juste le partager.

J'ai trouvé ce code à la recherche d'une solution. Pas sûr si cela fonctionne sur toutes les versions de MSSQL, j'ai MSSQL 2016.

declare @value as nvarchar(50) = 23
select REPLACE(STR(CAST(@value AS INT) + 1,4), SPACE(1), '0') as Leadingzero

renvoie "0023" Le 4 dans la fonction STR est la longueur totale, valeur comprise. Les exemples 4, 23 et 123 auront tous 4 dans STR et la quantité correcte de zéros sera ajoutée. Vous pouvez l'augmenter ou le diminuer. Pas besoin d'avoir la longueur sur le 23.

Edit: Je vois que c'est la même chose que @Anon post.

1
Niel Buys

Essayez ceci avec une longueur fixe.

select right('000000'+'123',5)

select REPLICATE('0', 5 - LEN(123)) + '123'
0
Dr.Stark

Pour une approche plus dynamique, essayez ceci. 

declare @val varchar(5)
declare @maxSpaces int
set @maxSpaces = 3
set @val = '3'
select concat(REPLICATE('0',@maxSpaces-len(@val)),@val)
0
ncastillo