Проблема с корректной заменой сокращенного текста в SQL

Я пытаюсь заменить кучу трудных для расшифровки сокращений соответствующими подробными описаниями. У меня есть таблица под названием "Сокращения", которая просто содержит список сокращений, которые нужно искать, и соответствующие описания, на которые они должны быть изменены. Кроме того, таблица "Replaced" содержит список неизмененных сокращенных описаний, которые я хотел бы изменить в одном столбце под названием "DescriptionCodes".

Данные, которые я пытаюсь изменить, представляют собой список различных чаев. Например, запись "TADIN HB GR" будет сокращением от "TADIN HERBAL BAG GREEN"

Код SQL, который я сейчас использую, выглядит следующим образом:

BEGIN TRANSACTION
DECLARE @Desc varchar(500)
DECLARE @Abbr varchar(500)

DECLARE contact_cursor CURSOR FOR
SELECT Description, Abbrv FROM dbo.Abbreviations

OPEN contact_cursor

FETCH NEXT FROM contact_cursor
INTO @Desc, @Abbr

WHILE @@FETCH_STATUS = 0
BEGIN
  PRINT 'Changing ' + @Abbr + ' to ' + @Desc

  UPDATE Replaced
  SET DescriptionCodes = REPLACE(DescriptionCodes, @Abbr, @Desc)
  WHERE DescriptionCodes LIKE CONCAT('% ', @Abbr, ' %')

  FETCH NEXT FROM contact_cursor
  INTO @Desc, @Abbr
END

CLOSE contact_cursor
DEALLOCATE contact_cursor

COMMIT

Конечно, проблема, с которой я сталкиваюсь, заключается в том, что после применения аббревиатуры подробное описание может содержать подстроку, соответствующую другой аббревиатуре, которая затем применяется. Например, PKG может быть изменен на PACKAGE, но PA также является аббревиатурой для PINEAPPLE, что означает, что после применения этого изменения конечный результат будет PINEAPPLECKAGE. Каждое сокращение имеет по одному пробелу с каждой стороны, поэтому я решил использовать этот факт, чтобы не обновлять аббревиатуру без пробела с обеих сторон, поэтому в моем коде присутствует CONCAT('% ', @Abbr, ' %'). Тем не менее, когда я пытаюсь этот метод в принципе ничего не меняется. Я смог увидеть ограниченный успех, сняв это ограничение, но тогда возникает другая проблема. Любые идеи относительно того, как я мог бы убедиться, что только вхождения аббревиатур с пробелами по обе стороны рассматриваются и обновляются?

ОБНОВЛЕНИЕ: попробовав несколько решений, опубликованных здесь, я все еще не смог заставить его работать, и я не уверен, почему. Судя по всему это правильно. Вот пример некоторых данных, с которыми я работаю:

JUSTEA HBL PKG CMCL CHM LG LR  1.5OZ
PRIDE OF INDIA BG ASM B BKFST  25 CT
CTL BR H-B 7BLSM PP            1 CT
POSTI H-B HRH CRN              20 CT
DRS H-B EPGP LPLDS PTVP TGN    20 CT
ULTLC BG CHG                   100 CT
PG TIPS BG D B                 40 CT
RPBL R-B B HLDY FT BLD         6 CT

Это нормально и выглядит так, как будто должно конвертироваться без проблем. Тем не менее, когда я запускаю код с указанными пробелами (как в случае с "LIKE '% ' + @Abbr + ' %'", который был моим первым наклоном), данные остаются полностью неизменными. Если я удаляю их, данные становятся совершенно неразборчивыми. Например, строка, начинающаяся с PRIDE OF INDIA, становится

ГОРДОСТЬ ИНДИИ (N) ИРЛАНДСКИЙ ДЕНЬ ЧЕРНЫЙ AG ASIA PLUM RICOT SPICE(D) СЕРЬЕЗНЫЙ ЧЕРНЫЙ ЧЕРНЫЙ KFST 25 СМЕСЬ И ПОМОЩЬ NT

Мне кажется, я должен отметить, что эти данные изначально были импортированы из таблиц Excel. Есть ли шанс, что это как-то связано с тем, что пробелы не распознаются?

3 ответа

Я думаю, что вам нужно обновлять каждую запись Замененной таблицы несколько раз, и вам нужно учитывать 4 местоположения сокращений (Один, Первый, Посередине, Последний). Что-то вроде этого:

DECLARE @Replaced TABLE ([DescriptionCodes] varchar(50))
DECLARE @Abbreviations TABLE ([Abbrv] varchar(50), [Description] varchar(50))

INSERT INTO @Replaced([DescriptionCodes]) VALUES ('TADIN H-B GR')
INSERT INTO @Replaced([DescriptionCodes]) VALUES ('PKG')
INSERT INTO @Replaced([DescriptionCodes]) VALUES ('PKG PA')

INSERT INTO @Abbreviations([Abbrv], [Description]) VALUES ('H-B', 'HERBAL BAG')
INSERT INTO @Abbreviations([Abbrv], [Description]) VALUES ('GR', 'GREEN')
INSERT INTO @Abbreviations([Abbrv], [Description]) VALUES ('PKG', 'PACKAGE')
INSERT INTO @Abbreviations([Abbrv], [Description]) VALUES ('PA', 'PINAPPLE')

DECLARE @RowCount int;

WHILE 1 = 1
BEGIN
    SET @RowCount = 0;

    UPDATE r
    SET r.[DescriptionCodes] = REPLACE(r.[DescriptionCodes], a.[Abbrv], a.[Description])
    FROM @Replaced r join @Abbreviations a ON r.[DescriptionCodes] = a.[Abbrv];
    SET @RowCount = @RowCount + @@RowCount;

    UPDATE r
    SET r.[DescriptionCodes] = REPLACE(r.[DescriptionCodes], ' ' + a.[Abbrv] + ' ', ' ' + a.[Description] + ' ')
    FROM @Replaced r join @Abbreviations a ON r.[DescriptionCodes] like '% ' + a.[Abbrv] + ' %';
    SET @RowCount = @RowCount + @@RowCount;

    UPDATE r
    SET r.[DescriptionCodes] = REPLACE(r.[DescriptionCodes], ' ' + a.[Abbrv],' ' + a.[Description])
    FROM @Replaced r join @Abbreviations a ON r.[DescriptionCodes] like '% ' + a.[Abbrv];
    SET @RowCount = @RowCount + @@RowCount;

    UPDATE r
    SET r.[DescriptionCodes] = REPLACE(r.[DescriptionCodes], a.[Abbrv] + ' ', a.[Description] + ' ')
    FROM @Replaced r join @Abbreviations a ON r.[DescriptionCodes] like a.[Abbrv] + ' %';
    SET @RowCount = @RowCount + @@RowCount;

    IF @ROWCOUNT = 0 BREAK;
END

SELECT * FROM @Replaced

Зачем использовать "LIKE", если вы собираетесь добавить пробелы? просто делать:

WHERE DescriptionCodes = @Abbr

Вы можете сделать это, и оно достигнет того, что вы пытаетесь сделать:

  LIKE '% ' + @Abbr + ' %'
Другие вопросы по тегам