SQL Server заменить, удалить все после определенного символа
Мои данные выглядят как
ID MyText
1 some text; some more text
2 text again; even more text
Как я могу обновить MyText, чтобы удалить все после полуколонии и включить в себя двоеточие, поэтому мне осталось следующее:
ID MyText
1 some text
2 text again
Я посмотрел на SQL Server Replace, но не могу думать о жизнеспособном способе проверки для ";"
Ответы
Ответ 1
Используйте LEFT в сочетании с CHARINDEX:
UPDATE MyTable
SET MyText = LEFT(MyText, CHARINDEX(';', MyText) - 1)
WHERE CHARINDEX(';', MyText) > 0
Обратите внимание, что предложение WHERE пропускает обновления строк, в которых нет точки с запятой.
Вот какой код для проверки работы SQL выше:
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
Получаю следующие результаты:
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)
Ответ 2
В то время, когда некоторые поля имеют ";" и некоторые из них вы также не можете добавить в поле "точка с запятой" и использовать тот же описанный метод.
SET MyText = LEFT(MyText+';', CHARINDEX(';',MyText+';')-1)
Ответ 3
Можно использовать CASE WHEN
, чтобы оставить те, у которых нет ';' в одиночестве.
SELECT
CASE WHEN CHARINDEX(';', MyText) > 0 THEN
LEFT(MyText, CHARINDEX(';', MyText)-1) ELSE
MyText END
FROM MyTable
Ответ 4
Используйте CHARINDEX
, чтобы найти ";". Затем используйте SUBSTRING
, чтобы просто вернуть часть до ";".
Ответ 5
UPDATE MyTable
SET MyText = SUBSTRING(MyText, 1, CHARINDEX(';', MyText) - 1)
WHERE CHARINDEX(';', MyText) > 0
Ответ 6
В ситуациях, когда мне нужно заменить или сопоставить (найти) что-то против строки, я предпочитаю использовать регулярные выражения.
Так как регулярные выражения не полностью поддерживаются в T-SQL
, вы можете реализовать их с помощью функций CLR
. Кроме того, вам не нужны никакие знания C#
или CLR
вообще, поскольку все, что вам нужно, уже доступно в MSDN String Utility Functions Sample.
В вашем случае решение с использованием регулярных выражений:
SELECT [dbo].[RegexReplace] ([MyColumn], '(;.*)', '')
FROM [dbo].[MyTable]
Но реализация такой функции в вашей базе данных поможет вам решить более сложные проблемы.
В приведенном ниже примере показано, как развернуть только функцию [dbo].[RegexReplace]
, но я рекомендую вам развернуть весь класс String Utility
.
-
Включение интеграции CLR. Выполните следующие команды Transact-SQL:
sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO
-
Настраивание кода (или создание .dll
). Generraly, вы можете сделать это, используя командную строку Visual Studio или .NET Framework (как показано в статье), но я предпочитаю использовать визуальную студию.
-
создать новый проект библиотеки классов:
![enter image description here]()
-
скопируйте и вставьте следующий код в файл 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);
}
}
-
создайте решение и получите путь к созданному файлу .dll
:
![enter image description here]()
-
замените путь к файлу .dll
в следующих операциях T-SQL
и выполните их:
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
-
Что это. Проверьте свою функцию:
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