Supprimer le dernier caractère d'une chaîne dans T-SQL?


139

Comment supprimer le dernier caractère d'une chaîne dans T-SQL?

Par exemple:

'TEST STRING'

rendre:

'TEST STRIN'

Réponses:


195

par exemple

DECLARE @String VARCHAR(100)
SET @String = 'TEST STRING'

-- Chop off the end character
SET @String = 
     CASE @String WHEN null THEN null 
     ELSE (
         CASE LEN(@String) WHEN 0 THEN @String 
            ELSE LEFT(@String, LEN(@String) - 1) 
         END 
     ) END


SELECT @String

71
Alternativement: SELECT LEFT (YourColumnName, LEN (YourColumnName) - 1) FROM YourTable
Kyle B.

3
Merci pour la capture nulle - ISNULL (LEFT (@String, LEN (@String) - 1), 'ErrMsg') résoudra
Volvox

2
@Volvox, il lancera toujours une exception si la chaîne est une chaîne vide, je modifie votre réponse pour gérer ce scénario.
Imran Rizvi

106

Si pour une raison quelconque votre logique de colonne est complexe (cas où ... alors ... sinon ... fin), alors les solutions ci-dessus vous obligent à répéter la même logique dans la fonction len (). Dupliquer la même logique devient un gâchis. Si tel est le cas, il s'agit d'une solution à noter. Cet exemple supprime la dernière virgule indésirable. J'ai finalement trouvé une utilisation pour la fonction REVERSE.

select reverse(stuff(reverse('a,b,c,d,'), 1, 1, ''))

6
Notez que ce code renvoie NULLs'il est passé une chaîne qui est plus courte que la plage de suppression spécifiée pour STUFF. Enveloppez-le dans un ISNULLpour obtenir une valeur de sortie différente pour la casse de chaîne vide.
Rozwel

11
Bien, utiliser ceci avec une application externe, avec un chemin for xml ('') pour éliminer une virgule à la fin. awseome
Tracker1

Également de la même manière que @ Tracker1. Contrairement à tout ce qui implique LEN (), cela fonctionne gracieusement (sans rien répéter) pour une chaîne vide (en particulier enveloppée dans ISNULL ())
gregmac

Il est vraiment remarquable de voir à quel point SQL peut parfois être brutal. C'est incroyable.
eouw0o83hf

Merci, cela m'a aidé, dans mon cas, j'avais un dernier espace donc le premier indice est 2select reverse(stuff(reverse('a,b,c,d,'), 2, 1, ''))
Arngue

52

Essaye ça:

select substring('test string', 1, (len('test string') - 1))

@Adrien une idée de pourquoi cela semble donner le même résultat que select substring('test string', 0, len('test string'))?
Louis Waweru

@Louis, la syntaxe est substring suit que: SUBSTRING ( expression ,start , length ). Désormais, les deux requêtes renvoient la même chose car la numérotation est basée sur 1, ce qui signifie que le premier caractère de l'expression est 1. Si start est inférieur à 1, l'expression renvoyée commencera au premier caractère spécifié dans expression. Source
JS5

26

Si votre chaîne est vide,

DECLARE @String VARCHAR(100)
SET @String = ''
SELECT LEFT(@String, LEN(@String) - 1)

alors ce code provoquera le message d'erreur «Paramètre de longueur non valide passé à la fonction de sous-chaîne».

Vous pouvez le gérer de cette façon:

SELECT LEFT(@String, NULLIF(LEN(@String)-1,-1))

Il retournera toujours résultat, et NULL en cas de chaîne vide.



9

Cela fonctionnera même lorsque le texte source / var est nul ou vide:

SELECT REVERSE(SUBSTRING(REVERSE(@a), 2, 9999))

2
C'est un commentaire sous-estimé, c'est rapide et il n'est pas nécessaire de sélectionner la chaîne deux fois pour fonctionner.
Randall

7

Si votre colonne est textet non varchar, vous pouvez utiliser ceci:

SELECT SUBSTRING(@String, 1, NULLIF(DATALENGTH(@String)-1,-1))

5

Si vous voulez faire cela en deux étapes, plutôt que les trois de REVERSE-STUFF-REVERSE, vous pouvez avoir votre séparateur de liste d'un ou deux espaces. Ensuite, utilisez RTRIM pour couper les espaces de fin et REMPLACER pour remplacer les doubles espaces par ','

select REPLACE(RTRIM('a  b  c  d  '),'  ', ', ')

Cependant, ce n'est pas une bonne idée si votre chaîne d'origine peut contenir des espaces internes.

Pas sûr de la performance. Chaque REVERSE crée une nouvelle copie de la chaîne, mais STUFF est un tiers plus rapide que REPLACE.

voir aussi ça




2

vous pouvez créer une fonction

CREATE FUNCTION [dbo].[TRUNCRIGHT] (@string NVARCHAR(max), @len int = 1)
RETURNS NVARCHAR(max)
AS
BEGIN
    IF LEN(@string)<@len
        RETURN ''
    RETURN LEFT(@string, LEN(@string) - @len)
END

2

Essaye ça

DECLARE @String VARCHAR(100)
SET @String = 'TEST STRING'
SELECT LEFT(@String, LEN(@String) - 1) AS MyTrimmedColumn

2

Obtenez le dernier personnage

Right(@string, len(@String) - (len(@String) - 1))

Je ne pense pas que ce soit ce qu'il demandait, cependant - cela pourrait être utile de faire un commentaire, cependant.
jimwise

3
juste à droite (@string, 1).
Objectif

1

Ma réponse est similaire à la réponse acceptée, mais elle vérifie également les chaînes Null et Empty.

DECLARE @String VARCHAR(100)

SET @String = 'asdfsdf1'

-- If string is null return null, else if string is empty return as it is, else chop off the end character
SET @String = Case @String when null then null else (case LEN(@String) when 0 then @String else LEFT(@String, LEN(@String) - 1) end ) end

SELECT @String

1

C'est assez tard, mais curieusement jamais mentionné.

select stuff(x,len(x),1,'')

c'est à dire:

take a string x
go to its last character
remove one character
add nothing

0

J'adore la réponse de @ bill-hoenig; cependant, j'utilisais une sous-requête et j'ai été rattrapé parce que la fonction REVERSE avait besoin de deux ensembles de parenthèses. Il m'a fallu du temps pour comprendre celui-là!

SELECT
   -- Return comma delimited list of all payment reasons for this Visit
   REVERSE(STUFF(REVERSE((
        SELECT DISTINCT
               CAST(CONVERT(varchar, r1.CodeID) + ' - ' + c.Name + ', ' AS VARCHAR(MAX))
          FROM VisitReason r1
          LEFT JOIN ReasonCode c        ON c.ID = r1.ReasonCodeID
         WHERE p.ID = r1.PaymentID
         FOR XML PATH('')
              )), 1, 2, ''))                        ReasonCode
  FROM Payments p

Vous souhaiterez peut-être utiliser une application externe / croisée pour la partie composite de la requête. J'utilise ceci pour obtenir un ensemble d'indicateurs pour un élément parent.
Tracker1

0

Pour mettre à jour l'enregistrement en coupant les N derniers caractères d'une colonne particulière:

UPDATE tablename SET columnName = LEFT(columnName , LEN(columnName )-N) where clause

0

Essayez-le:

  DECLARE @String NVARCHAR(100)
    SET @String = '12354851'
    SELECT LEFT(@String, NULLIF(LEN(@String)-1,-1))

0
declare @string varchar(20)= 'TEST STRING'
Select left(@string, len(@string)-1) as Tada

production:

Tada
--------------------
TEST STRIN

0

Essaye ça,

DECLARE @name NVARCHAR(MAX) SET @name='xxxxTHAMIZHMANI****'SELECT Substring(@name, 5, (len(@name)-8)) as UserNames

Et la sortie sera comme, THAMIZHMANI


-1
declare @x varchar(20),@y varchar(20)
select @x='sam'
select 
case when @x is null then @y
      when @y is null then @x
      else @x+','+@y
end


go

declare @x varchar(20),@y varchar(20)
select @x='sam'
--,@y='john'
DECLARE @listStr VARCHAR(MAX)   

SELECT @listStr = COALESCE(@x + ', ' ,'') +coalesce(@y+',','')
SELECT left(@listStr,len(@listStr)-1)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.