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'
Daveed
la source

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
AdaTheDev
la source
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, ''))
Bill Hoenig
la source
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
la source
@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.

Max Grachev
la source
10
select left('TEST STRING', len('TEST STRING')-1)
greg121
la source
9

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

SELECT REVERSE(SUBSTRING(REVERSE(@a), 2, 9999))
David Roach
la source
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))
MicBehrens
la source
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

Daryl
la source
5
@result = substring(@result, 1, (LEN(@result)-1))
farrukh saleem
la source
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
Mihail Katrikh
la source
2

Essaye ça

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

Obtenez le dernier personnage

Right(@string, len(@String) - (len(@String) - 1))
Sam
la source
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
Imran Rizvi
la source
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
George Menoutis
la source
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
hurleystylee
la source
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
Manvendra_0611
la source
0

Essayez-le:

  DECLARE @String NVARCHAR(100)
    SET @String = '12354851'
    SELECT LEFT(@String, NULLIF(LEN(@String)-1,-1))
Chili
la source
0
declare @string varchar(20)= 'TEST STRING'
Select left(@string, len(@string)-1) as Tada

production:

Tada
--------------------
TEST STRIN
Migo
la source
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

Thamizhmani
la source
-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)
Julie
la source