web-dev-qa-db-fra.com

SQL Server remplacer, supprimer tout après certain caractère

Mes données ressemblent à

ID    MyText
1     some text; some more text
2     text again; even more text

Comment puis-je mettre à jour MyText pour tout supprimer après le point-virgule, y compris le point-virgule?

ID    MyText
1     some text
2     text again

J'ai jeté un œil à SQL Server Replace , mais je ne trouve pas de moyen viable de rechercher le ";"

48
Jimmy

Utilisez GAUCHE combiné avec CHARINDEX:

UPDATE MyTable
SET MyText = LEFT(MyText, CHARINDEX(';', MyText) - 1)
WHERE CHARINDEX(';', MyText) > 0

Notez que la clause WHERE ignore la mise à jour des lignes dans lesquelles il n'y a pas de point-virgule.

Voici du code pour vérifier que le SQL ci-dessus fonctionne:

declare @MyTable table ([id] int primary key clustered, MyText varchar(100))
insert into @MyTable ([id], MyText)
select 1, 'some text; some more text'
union all select 2, 'text again; even more text'
union all select 3, 'text without a semicolon'
union all select 4, null -- test NULLs
union all select 5, '' -- test empty string
union all select 6, 'test 3 semicolons; second part; third part;'
union all select 7, ';' -- test semicolon by itself    

UPDATE @MyTable
SET MyText = LEFT(MyText, CHARINDEX(';', MyText) - 1)
WHERE CHARINDEX(';', MyText) > 0

select * from @MyTable

J'obtiens les résultats suivants:

id MyText
-- -------------------------
1  some text
2  text again
3  text without a semicolon
4  NULL
5        (empty string)
6  test 3 semicolons
7        (empty string)
93
Paul Williams

Pour les moments où certains champs ont un ";" et d'autres non, vous pouvez également ajouter un point-virgule au champ et utiliser la même méthode que celle décrite précédemment.

SET MyText = LEFT(MyText+';', CHARINDEX(';',MyText+';')-1)
18
Rashlien

Pourrait utiliser CASE WHEN laisser ceux qui n'ont pas de ';' seul.

    SELECT
    CASE WHEN CHARINDEX(';', MyText) > 0 THEN
    LEFT(MyText, CHARINDEX(';', MyText)-1) ELSE
    MyText END
    FROM MyTable
11
Rookie

Utilisez CHARINDEX pour trouver le ";". Puis utilisez SUBSTRING pour simplement renvoyer la partie avant le ";".

3
David
UPDATE MyTable
   SET MyText = SUBSTRING(MyText, 1, CHARINDEX(';', MyText) - 1)
 WHERE CHARINDEX(';', MyText) > 0 
2
manji

Pour les situations où je dois remplacer ou trouver quelque chose contre une chaîne, je préfère utiliser des expressions régulières.

Depuis, les expressions régulières ne sont pas complètement supportées dans T-SQL, Vous pouvez les implémenter en utilisant les fonctions CLR. De plus, vous n'avez besoin d'aucune connaissance de C# Ou CLR car tout ce dont vous avez besoin est déjà disponible dans MSDN exemple de fonctions utilitaires de chaîne .

Dans votre cas, la solution utilisant des expressions régulières est la suivante:

SELECT [dbo].[RegexReplace] ([MyColumn], '(;.*)', '')
FROM [dbo].[MyTable]

Cependant, la mise en œuvre d'une telle fonction dans votre base de données va vous aider à résoudre des problèmes plus complexes.


L'exemple ci-dessous montre comment déployer uniquement la fonction [dbo].[RegexReplace], Mais je vous recommanderai de déployer toute la classe String Utility.

  1. Activation de l'intégration CLR. Exécutez les commandes Transact-SQL suivantes:

    sp_configure 'clr enabled', 1
    GO
    RECONFIGURE
    GO  
    
  2. Réduire le code (ou créer le .dll). De manière générale, vous pouvez le faire en utilisant l'invite de commande Visual Studio ou .NET Framework (comme indiqué dans l'article), mais je préfère utiliser Visual Studio.

    • créer un nouveau projet de bibliothèque de classes:

      enter image description here

    • copiez et collez le code suivant dans le fichier Class1.cs:

      using System;
      using System.IO;
      using System.Data.SqlTypes;
      using System.Text.RegularExpressions;
      using Microsoft.SqlServer.Server;
      
      public sealed class RegularExpression
      {
          public static string Replace(SqlString sqlInput, SqlString sqlPattern, SqlString sqlReplacement)
          {
              string input = (sqlInput.IsNull) ? string.Empty : sqlInput.Value;
              string pattern = (sqlPattern.IsNull) ? string.Empty : sqlPattern.Value;
              string replacement = (sqlReplacement.IsNull) ? string.Empty : sqlReplacement.Value;
              return Regex.Replace(input, pattern, replacement);
          }
      }
      
    • construisez la solution et obtenez le chemin du fichier .dll créé:

      enter image description here

    • remplacez le chemin d'accès au fichier .dll dans les instructions T-SQL suivantes et exécutez-les:

      IF OBJECT_ID(N'RegexReplace', N'FS') is not null
      DROP Function RegexReplace;
      GO
      
      IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'StringUtils')
      DROP Assembly StringUtils;
      GO
      
      DECLARE @SamplePath nvarchar(1024)
      -- You will need to modify the value of the this variable if you have installed the sample someplace other than the default location.
      Set @SamplePath = 'C:\Users\gotqn\Desktop\StringUtils\StringUtils\StringUtils\bin\Debug\'
      CREATE Assembly [StringUtils] 
      FROM @SamplePath + 'StringUtils.dll'
      WITH permission_set = Safe;
      GO
      
      
      CREATE FUNCTION [RegexReplace] (@input nvarchar(max), @pattern nvarchar(max), @replacement nvarchar(max))
      RETURNS nvarchar(max)
      AS EXTERNAL NAME [StringUtils].[RegularExpression].[Replace]
      GO
      
    • C'est ça. Testez votre fonction:

      declare @MyTable table ([id] int primary key clustered, MyText varchar(100))
      insert into @MyTable ([id], MyText)
      select 1, 'some text; some more text'
      union all select 2, 'text again; even more text'
      union all select 3, 'text without a semicolon'
      union all select 4, null -- test NULLs
      union all select 5, '' -- test empty string
      union all select 6, 'test 3 semicolons; second part; third part'
      union all select 7, ';' -- test semicolon by itself    
      
      SELECT [dbo].[RegexReplace] ([MyText], '(;.*)', '')
      FROM @MyTable
      
      select * from @MyTable
      
1
gotqn