Заменить символы в каждом слове большой строки в базе данных

У меня есть столбец типа 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

Как получить желаемый результат вывода?

T-SQL — не лучший язык для этого (поскольку это не язык обработки текста). Есть ли причина, по которой вы не можете исправить это в коде приложения?

Dai 05.08.2024 09:42

@Dai, у меня в таблице большие данные, написанные арабскими символами, и я хочу их преобразовать, и результат будет таким.

saeed ahmed 05.08.2024 09:47

@Dai Я знаю, что могу сделать это на C#, но это долгий процесс. Возможно, используя SQL, я смогу сделать это за один шаг.

saeed ahmed 05.08.2024 09:49

Возможно, вы сможете добиться этого с помощью наборов, но я подозреваю, что это будет очень медленно. Язык программирования подходит гораздо лучше.

Thom A 05.08.2024 09:50

@ThomA Я подумал задать вопрос и посмотреть, есть ли какое-нибудь решение

saeed ahmed 05.08.2024 09:52

Если есть решение, это не значит, что оно правильное, @saeedahmed. Вы можете использовать молоток, чтобы закрутить шуруп в стену, это «сработает», но создаст беспорядок.

Thom A 05.08.2024 09:53

Я не знаю, как текст на арабском языке, но вы, вероятно, можете использовать тот факт, что слово начинается и заканчивается пробелом, и заменить его следующим образом: SELECT LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(N' ' + text + N' ', N' x', N'AAA'), N' x', N'ZZZ'), N'x', N'MMM')))

siggemannen 05.08.2024 13:12

Возможно ли, чтобы строка содержала отдельный x? Если да, то будете ли вы считать это началом, серединой или концом или преобразуете одиночный x в AAAMMMZZZ? Что вы считаете словом? Другими словами: что ограничивает слова? Пробелы, запятые, тире, цифры,...?

Thorsten Kettner 06.08.2024 12:38

@ThorstenKettner На самом деле, я привел этот пример для текстовых данных в базе данных на арабском языке или урду, которые будут заменены другими буквами.

saeed ahmed 06.08.2024 12:49
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
9
106
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Предполагая, что вы можете использовать новые (настоящие) функции регулярных выражений в 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 (как отмечено).

Martin Smith 06.08.2024 10:24

@MartinSmith Прямо сейчас я использую функции регулярных выражений T-SQL в своих базах данных SQL Azure.

Dai 06.08.2024 10:27

Это отмечено тегом SQL Server, а не azure-sql-database

Martin Smith 06.08.2024 10:28

@MartinSmith Привет, ОП все равно уже принял мой ответ, так что, может быть, они тоже используют Azure SQL, но просто пометили свой вопрос SQL Server, чтобы избежать спама тегов?

Dai 06.08.2024 10:29

Или, может быть, они даже не пробовали это

Martin Smith 06.08.2024 10:29

@MartinSmith Всегда оптимист!

Dai 06.08.2024 10:30

@Dai Я использую SQL Server 2019. Не могли бы вы предложить решение для этой версии?

saeed ahmed 06.08.2024 11:52
Ответ принят как подходящий

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
  1. Затем используйте следующие команды

    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 

Это дает результат

Вы также можете использовать большой текст, как показано ниже.

Из любопытства вы рассматривали настройку вашей ФУНКЦИИ, чтобы ее можно было встроить? Это не слишком большая дополнительная работа, но приводит к гораздо лучшим планам.

Dai 06.08.2024 10:31

Моя цель — разработать решение, которое было бы более читабельным, управляемым и расширяемым. это пошаговое решение. Я не стремился разработать решение, которое было бы сжатым, быстрым, оптимизированным, но слишком сложным для расширения.

FevziKartal 06.08.2024 10:49

Я ценю это, но не думаю, что встраивание вашей функции вообще поставит под угрозу читабельность.

Dai 06.08.2024 10:50

@FevziKartal Он не работает, если трижды заменить x на AAA, если он появляется в начале слова в строке.

saeed ahmed 06.08.2024 11:49

@FevziKartal Конечный результат будет таким: Это teMMMt со слишком большим количеством символов AAAZZZ AAAanthic miZZZ eMMMcite AAAeroZZZ oZZZ maMMMimise

saeed ahmed 06.08.2024 11:57

@саид Ахмед, я проверю и изменю решение

FevziKartal 06.08.2024 12:00

@саид Ахмед, я немного изменил функцию. Теперь это дает точный результат.

FevziKartal 06.08.2024 12:31

Другие вопросы по теме