У меня есть столбец типа NVARCHAR(MAX)
в базе данных моего SQL-сервера, и теперь я хочу заменить любые символы слова в строке.
Строка выглядит следующим образом:
DECLARE @Description NVARCHAR(MAX)
SET @Description = 'This is text with far too much xx char xanthic Mix Excise xerox Ox Maximize'
SELECT
@Description,
REPLACE(@Description,"x", "how replace x with AAA MMM ZZZ")
Если x
находится в середине слова в строке, замените его три раза на MMM
. Если x появляется в начале слова в строке, замените его три раза на AAA. Если x находится в конце слова в строке, замените его три раза на ZZZ.
Я хочу, чтобы выходная строка была такой:
This is teMMMt with far too much AAAZZZ char AAAanthic miZZZ eMMMcise AAAeroZZZ oZZZ maMMMimise
Как получить желаемый результат вывода?
@Dai, у меня в таблице большие данные, написанные арабскими символами, и я хочу их преобразовать, и результат будет таким.
@Dai Я знаю, что могу сделать это на C#, но это долгий процесс. Возможно, используя SQL, я смогу сделать это за один шаг.
Возможно, вы сможете добиться этого с помощью наборов, но я подозреваю, что это будет очень медленно. Язык программирования подходит гораздо лучше.
@ThomA Я подумал задать вопрос и посмотреть, есть ли какое-нибудь решение
Если есть решение, это не значит, что оно правильное, @saeedahmed. Вы можете использовать молоток, чтобы закрутить шуруп в стену, это «сработает», но создаст беспорядок.
Я не знаю, как текст на арабском языке, но вы, вероятно, можете использовать тот факт, что слово начинается и заканчивается пробелом, и заменить его следующим образом: SELECT LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(N' ' + text + N' ', N' x', N'AAA'), N' x', N'ZZZ'), N'x', N'MMM')))
Возможно ли, чтобы строка содержала отдельный x? Если да, то будете ли вы считать это началом, серединой или концом или преобразуете одиночный x в AAAMMMZZZ? Что вы считаете словом? Другими словами: что ограничивает слова? Пробелы, запятые, тире, цифры,...?
@ThorstenKettner На самом деле, я привел этот пример для текстовых данных в базе данных на арабском языке или урду, которые будут заменены другими буквами.
Предполагая, что вы можете использовать новые (настоящие) функции регулярных выражений в SQL Server vNext/SQL Server 2025 или Azure SQL, тогда это выполнимо...
Во-первых, давайте просто проигнорируем часть SQL и просто разберемся с регулярными выражениями:
Если
x
находится в середине слова в строке, замените его три раза наMMM
.
Для этого используйте \Bx\B
, который соответствует любому символу x
, но только если он не является первым или последним символом в слове (последовательность символов).
непробельные буквенно-цифровые символы).
Используя режим подстановки Regex101, мы можем преобразовать это...:
В этом тексте слишком много символов xx xanthic Mix Excision xerox Ox Maximize
...к этому:
Это теМММт со слишком большим количеством xx char xanthic Mix EMMMcite xerox Ox MaMMMimize
Если x появляется в начале слова в строке, замените его три раза на AAA.
Это \bx\B
: \b
соответствует разрыву слова (т. е. пробелу), а \B
соответствует разрыву, не являющемуся словом.
Если x находится в конце слова в строке, замените его три раза на ZZZ.
Точно так же это будет \Bx\b
.
... теперь о части SQL:
DECLARE @text nvarchar(4000) = N'This is text with far too much xx char xanthic Mix Excise xerox Ox Maximize';
-- Replace initial leading 'x' with 'AAA':
SET @text = REGEXP_REPLACE( @text, N'\bx\B', N'AAA' );
-- Replace any trailing 'x' with 'ZZZ':
SET @text = REGEXP_REPLACE( @text, N'\Bx\b', N'ZZZ' );
-- Replace any 'x' inside a sequence of word-chars with 'MMM':
SET @text = REGEXP_REPLACE( @text, N'\Bx\B', N'MMM' );
... приведенный выше T-SQL демонстрирует, как применить преобразование к скалярной переменной nvarchar
, @text
.
Для UPDATE
или MERGE
отношения (т. е. TABLE
, VIEW
, CTE и т. д.) просто адаптируйте вышеизложенное. Не забудьте иметь хорошее предложение WHERE
, чтобы SQL Server не переписывал записи, которые на самом деле не нуждаются в обновлении (и это еще более важно, если вы используете временные таблицы).
UPDATE
tbl
OUTPUT
inserted.PKCol,
deleted .Text AS OldText,
inserted.Text AS NewText
SET
Text = REGEXP_REPLACE(
REGEXP_REPLACE(
REGEXP_REPLACE(
Text,
N'\bx\B',
N'AAA'
),
N'\Bx\b',
N'ZZZ'
),
N'\Bx\B',
N'MMM'
)
WHERE
REGEXP_LIKE( Text, N'\bx\B' )
OR
REGEXP_LIKE( Text, N'\Bx\b' )
OR
REGEXP_LIKE( Text, N'\Bx\B' );
«Предполагая, что вы можете использовать» — это довольно серьезное предположение, поскольку в настоящее время оно недоступно ни в одной версии SQL Server (как отмечено).
@MartinSmith Прямо сейчас я использую функции регулярных выражений T-SQL в своих базах данных SQL Azure.
Это отмечено тегом SQL Server, а не azure-sql-database
@MartinSmith Привет, ОП все равно уже принял мой ответ, так что, может быть, они тоже используют Azure SQL, но просто пометили свой вопрос SQL Server, чтобы избежать спама тегов?
Или, может быть, они даже не пробовали это
@MartinSmith Всегда оптимист!
@Dai Я использую SQL Server 2019. Не могли бы вы предложить решение для этой версии?
1.) Сначала создайте функцию
CREATE FUNCTION [dbo].[WordConvert](@SourceWord NVARCHAR(250))
RETURNS NVARCHAR(250)
AS
BEGIN
DECLARE @TargetWord NVARCHAR(250)=''
DECLARE @Words NVARCHAR(250)
DECLARE @C NVARCHAR(10)
DECLARE @WLEN INT
DECLARE @I INT
SET @Words = @SourceWord
SET @WLEN= LEN(@Words)
SET @I = 1
SET @TargetWord=''
WHILE(@I < LEN(@Words)+1)
BEGIN
SELECT @C = SUBSTRING(@words,@I,1)
IF @C!='x'
SET @TargetWord=@TargetWord + @C
IF (@C='x' and @I=1 )
SET @TargetWord=@TargetWord +'AAA'
IF @C='x' and @I=@WLEN
SET @TargetWord=@TargetWord + 'ZZZ'
IF @C='x' and (@I>1 AND @I<@WLEN)
SET @TargetWord=@TargetWord + 'MMM'
SET @I = @I + 1
END
RETURN @TargetWord
END
Затем используйте следующие команды
DECLARE @Description NVARCHAR(MAX)
DECLARE @TargetSentence NVARCHAR(MAX) SET @Description = 'This is text with far too much xx char xanthic Mix Excise xerox Ox Maximize' SELECT value As SourceWord, [dbo].[WordConvert](value ) As TargetWord FROM STRING_SPLIT(@Description, ' ')
Это дает результат
Затем соедините результат в Targetsentence или большой текст, как показано ниже:
DECLARE @Description NVARCHAR(MAX)
DECLARE @TargetSentence NVARCHAR(MAX)
SET @Description = 'This is text with far too much xx char xanthic Mix Excise xerox Ox Maximize'
SELECT @TargetSentence= CONCAT(@TargetSentence + ' ', '') + [dbo].[WordConvert](value )
FROM STRING_SPLIT(@Description, ' ')
SELECT @TargetSentence TargetSentence
Это дает результат
Вы также можете использовать большой текст, как показано ниже.
Из любопытства вы рассматривали настройку вашей ФУНКЦИИ, чтобы ее можно было встроить? Это не слишком большая дополнительная работа, но приводит к гораздо лучшим планам.
Моя цель — разработать решение, которое было бы более читабельным, управляемым и расширяемым. это пошаговое решение. Я не стремился разработать решение, которое было бы сжатым, быстрым, оптимизированным, но слишком сложным для расширения.
Я ценю это, но не думаю, что встраивание вашей функции вообще поставит под угрозу читабельность.
@FevziKartal Он не работает, если трижды заменить x на AAA, если он появляется в начале слова в строке.
@FevziKartal Конечный результат будет таким: Это teMMMt со слишком большим количеством символов AAAZZZ AAAanthic miZZZ eMMMcite AAAeroZZZ oZZZ maMMMimise
@саид Ахмед, я проверю и изменю решение
@саид Ахмед, я немного изменил функцию. Теперь это дает точный результат.
T-SQL — не лучший язык для этого (поскольку это не язык обработки текста). Есть ли причина, по которой вы не можете исправить это в коде приложения?