web-dev-qa-db-fra.com

Caractère SQL Server TRIM

J'ai la chaîne suivante: 'BOB *', comment puis-je couper le * pour qu'il apparaisse comme 'BOB'

J'ai essayé le RTRIM ('BOB *', '*') mais ne fonctionne pas comme dit nécessite seulement 1 paramètre.

12
Nate Pet
LEFT('BOB*', LEN('BOB*')-1)

devrait le faire.

2
paulmorriss

Voici un autre très bon moyen d'implémenter le TRIM char FROM string d'Oracle dans MS SQL Server :

  • Tout d'abord, vous devez identifier un caractère qui ne sera jamais utilisé dans votre chaîne, par exemple ~
  • Vous remplacez tous les espaces avec ce caractère
  • Vous remplacez le caractère * que vous voulez couper avec un espace
  • Vous LTrim + RTrim la chaîne obtenue
  • Vous remplacez tous les espaces par le caractère coupé *
  • Vous remplacez tous les caractères jamais utilisés par un espace

Par exemple:

REPLACE(REPLACE(LTrim(RTrim(REPLACE(REPLACE(string,' ','~'),'*',' '))),' ','*'),'~',' ')
20
Teejay
CREATE FUNCTION dbo.TrimCharacter
(
    @Value NVARCHAR(4000),
    @CharacterToTrim NVARCHAR(1)
)
RETURNS NVARCHAR(4000)
AS
BEGIN
    SET @Value = LTRIM(RTRIM(@Value))
    SET @Value = REVERSE(SUBSTRING(@Value, PATINDEX('%[^'+@CharacterToTrim+']%', @Value), LEN(@Value)))
    SET @Value = REVERSE(SUBSTRING(@Value, PATINDEX('%[^'+@CharacterToTrim+']%', @Value), LEN(@Value)))
    RETURN @Value
END
GO
--- Example
----- SELECT dbo.TrimCharacter('***BOB*********', '*')
----- returns 'BOB'
15
Chris Rodriguez

Si vous voulez supprimer tous les astérisques, alors c'est évident:

SELECT REPLACE('Hello*', '*', '')

Cependant , si vous avez plus d'un astérisque à la fin et plusieurs, mais que vous êtes seulement intéressé par la réduction des derniers, alors je l'utilise:

DECLARE @String VarChar(50) = '**H*i****'
SELECT LEFT(@String, LEN(REPLACE(@String, '*', ' ')))              --Returns: **H*i

J'ai mis à jour cette réponse pour inclure montrer comment supprimer les caractères principaux:

SELECT RIGHT(@String, LEN(REPLACE(REVERSE(@String), '*', ' ')))    --Returns: H*i****

LEN () a un "feature" (qui ressemble beaucoup à un bogue) où il ne compte pas les espaces de fin.

9
MikeTeeVee

Si vous souhaitez uniquement supprimer un seul caractère '*' de la valeur lorsque celle-ci se termine par un '*', une simple expression CASE le fera pour vous:

SELECT CASE WHEN RIGHT(foo,1) = '*' THEN LEFT(foo,LEN(foo)-1) ELSE foo END AS foo
  FROM (SELECT 'BOB*' AS foo)

Pour supprimer tous les caractères '*' finaux, vous avez besoin d'une expression plus complexe utilisant les fonctions REVERSE, PATINDEX, LEN et LEFT.

REMARQUE: Soyez prudent avec la fonction REPLACE, car elle remplacera toutes les occurrences du caractère spécifié dans la chaîne, et pas uniquement celles de fin.

4
spencer7593

Si vous souhaitez un comportement similaire à la façon dont RTRIM traite les espaces, c’est-à-dire que "B * O * B **" se transformerait en "B * O * B" sans perdre les éléments incorporés, quelque chose comme:

REVERSE(SUBSTRING(REVERSE('B*O*B**'), PATINDEX('%[^*]%',REVERSE('B*O*B**')), LEN('B*O*B**') - PATINDEX('%[^*]%', REVERSE('B*O*B**')) + 1))

Devrait le faire.

4
George

Que diriez-vous de .. (dans ce cas, pour couper les virgules ou les points)

Pour une variable:

-- Trim commas and full stops from end of City
WHILE RIGHT(@CITY, 1) IN (',', '.'))    
    SET @CITY = LEFT(@CITY, LEN(@CITY)-1)  

Pour les valeurs de table:

-- Trim commas and full stops from end of City
WHILE EXISTS (SELECT 1 FROM [sap_out_address] WHERE RIGHT([CITY], 1) IN (',', '.'))     
    UPDATE [sap_out_address]    
    SET [CITY] = LEFT([CITY], LEN([CITY])-1)  
    WHERE RIGHT([CITY], 1) IN (',', '.') 
2
Simon L

RRIM () LTRIM () supprime uniquement les espaces essayez http://msdn.Microsoft.com/en-us/library/ms186862.aspx

Fondamentalement, il suffit de remplacer le * par un espace vide 

REPLACE ('TextWithCharacterToReplace', 'CharacterToReplace', 'CharacterToReplaceWith')

Alors tu veux

REMPLACER ('BOB *', '*', '')

2
Purplegoldfish

Solution pour un paramètre de caractère:

rtrim ('0000100', '0') -> sélectionner à gauche ('0000100', len (rtrim (replace ('0000100', '0', ''))))

ltrim ('0000100', '0') -> sélectionner right ('0000100', len (remplacer (ltrim (remplacer ('0000100', '0', '')),}. ' ))

0
MilanKrsiak

Couper avec de nombreux cas

--id = 100 101 102 103 104 105 106 107 108 109 110 111
select right(id,2)+1  from ordertbl -- 1 2 3 4 5 6 7 8 9 10 11  -- last     two positions are taken

select LEFT('BOB', LEN('BOB')-1) -- BO

select LEFT('BOB*',1) --B
select LEFT('BOB*',2) --BO
0
Arun Prasad E S

Essaye ça:

Original

select replace('BOB*','*','')

Corrigé pour être un remplaçant exact

select replace('BOB*','BOB*','BOB')
0
datagod

La solution @eejay est géniale. Mais le code ci-dessous peut être plus compréhensible:

declare @X nvarchar(max)='BOB *'

set @X=replace(@X,' ','^')

set @X=replace(@X,'*',' ')

set @X= ltrim(rtrim(@X))

set @X=replace(@X,'^',' ')
0
CAGDAS AYDIN

J'ai utilisé une approche similaire à certaines des réponses ci-dessus, consistant à utiliser une correspondance de modèle et à inverser la chaîne pour trouver le premier caractère non ajustable, puis à la couper. La différence est que cette version fait moins de travail que les précédentes, elle devrait donc être un peu plus efficace.

  • Cela crée une fonctionnalité RTRIM pour tout caractère spécifié.
  • Il comprend une étape supplémentaire set @charToFind = case... pour échapper au caractère choisi.
  • Il y a actuellement un problème si @charToReplace est un crochet de droite (]) car il semble n'y avoir aucun moyen d'échapper à cela.

.

declare @stringToSearch nvarchar(max) = '****this is****a  ** demo*****'
, @charToFind nvarchar(5) = '*' 

--escape @charToFind so it doesn't break our pattern matching
set @charToFind = case @charToFind 
    when ']' then '[]]' --*this does not work / can't find any info on escaping right crotchet*
    when '^' then '\^'
    --when '%' then '%' --doesn't require escaping in this context
    --when '[' then '[' --doesn't require escaping in this context
    --when '_' then '_' --doesn't require escaping in this context
    else @charToFind
end

select @stringToSearch
, left
(
    @stringToSearch
    ,1 
    + len(@stringToSearch)
    - patindex('%[^' + @charToFind  + ']%',reverse(@stringToSearch))
)
0
JohnLBevan

SqlServer2017 propose une nouvelle méthode: https://docs.Microsoft.com/en-us/sql/t-sql/functions/trim-transact-sql?view=sql-server-2017

SELECT TRIM ('0' FROM '00001900'); -> 19

SELECT TRIM ('.,!' FROM '# test.'); -> # test

SELECT TRIM ('*' FROM 'BOB *'); -> BOB

Malheureusement, RTRIM ne permet pas de rogner un caractère spécifique.

0
Sergei Zinovyev

J'aime beaucoup la réponse de Teejay , et presque arrêté là. C'est intelligent, mais j'ai le sentiment "presque trop intelligent", car, d'une manière ou d'une autre, votre chaîne aura à un moment donné un ~ (ou autre) délibérément. Donc, ce n'est pas assez défensif pour que je mette en production.

J'aime Chris aussi , mais l'appel PATINDEX semble exagéré. 

Bien que ce soit probablement une micro-optimisation , en voici une sans PATINDEX:

CREATE FUNCTION dbo.TRIMMIT(@stringToTrim NVARCHAR(MAX), @charToTrim NCHAR(1))
RETURNS NVARCHAR(MAX)
AS
BEGIN
    DECLARE @retVal NVARCHAR(MAX)

    SET @retVal = @stringToTrim

    WHILE 1 = charindex(@charToTrim, reverse(@retVal))
        SET @retVal = SUBSTRING(@retVal,0,LEN(@retVal))

    WHILE 1 = charindex(@charToTrim, @retVal)
        SET @retVal = SUBSTRING(@retVal,2,LEN(@retVal))

    RETURN @retVal
END

--select dbo.TRIMMIT('\\trim\asdfds\\\', '\')
--trim\asdfds

Retourner un MAX nvarchar me gêne un peu, mais c'est la manière la plus flexible de le faire.

0
ruffin