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 ";"
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)
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)
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
Utilisez CHARINDEX
pour trouver le ";". Puis utilisez SUBSTRING
pour simplement renvoyer la partie avant le ";".
UPDATE MyTable
SET MyText = SUBSTRING(MyText, 1, CHARINDEX(';', MyText) - 1)
WHERE CHARINDEX(';', MyText) > 0
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
.
Activation de l'intégration CLR. Exécutez les commandes Transact-SQL suivantes:
sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO
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:
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éé:
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