Замените специальные символы на HTML-объекты - PullRequest
0 голосов
/ 16 октября 2018

У меня есть следующее в таблице TABLE

id    content
-------------------------------------
1     Hellö world, I äm text
2     ènd there äré many more chars
3     that are speçial in my dat£base

Теперь мне нужно экспортировать эти записи в файлы HTML, используя bcp:

set @command = 'bcp "select [content] from [TABLE] where [id] = ' + 
            @id queryout +' + @filename + '.html" -S ' + @instance +
            ' -c -U ' + @username + ' -P ' + @password"

exec xp_cmdshell @command, no_ouput

Чтобы вывод выглядел правильноМне нужно сначала заменить все специальные символы соответствующими им сущностями HTML (псевдо)

insert into [#temp_html] ..
replace(replace([content], 'ö', 'ö'), 'ä', 'ä')

Но сейчас у меня есть 30 вложенных replace с, и это начинает выглядеть безумно.

После долгих поисков я нашел этот пост, в котором используется таблица преобразования HTML , но он слишком сложен для меня, чтобы понять:

  1. В таблице не указаны специальные символы какони есть в моем тексте (ö, à и т. д.), но UnicodeHex.Нужно ли мне добавлять их в таблицу, чтобы сделать нужные мне преобразования?
  2. У меня возникают проблемы с пониманием того, как обновить мой скрипт, чтобы заменить все специальные символы.Может кто-нибудь показать мне фрагмент (псевдо) кода?

1 Ответ

0 голосов
/ 16 октября 2018

Один из способов сделать это с таблицей перевода - использовать рекурсивный cte для замены, и еще один cte, чтобы получить только последнюю строку каждого переведенного значения.

Сначала создайте и заполните образец таблицы( Пожалуйста, сохраните этот шаг в ваших будущих вопросах):

DECLARE @T AS TABLE
(
    id int,
    content nvarchar(100)
)
INSERT INTO @T (id, content) VALUES
(1,     'Hellö world, I äm text'),
(2,     'ènd there äré many more chars'),
(3,     'that are speçial in my dat£base')

Затем создайте и заполните таблицу перевода (я не знаю HTML-сущности для этих символов, поэтому ятолько что использовали цифры [плюс это легче увидеть в результатах]).Также обратите внимание, что это можно сделать с помощью еще одного cte в цепочке.

DECLARE @Translations AS TABLE
(
    str nchar(1),
    replacement nvarchar(10)
)

INSERT INTO @Translations (str, replacement) VALUES
('ö', '-1-'),
('ä', '-2-'),
('è', '-3-'),
('ä', '-4-'),
('é', '-5-'),
('ç', '-6-'),
('£', '-7-')

Теперь первый cte выполнит замены, а второй cte просто добавляет row_number, чтобы для каждого идентификатора,последнее значение lvl получит 1:

;WITH CTETranslations AS
(
    SELECT id, content, 1 As lvl
    FROM @T
    UNION ALL
    SELECT id, CAST(REPLACE(content, str, replacement) as nvarchar(100)), lvl+1
    FROM CTETranslations
    JOIN @Translations 
        ON content LIKE '%' + str + '%' 
), cteNumberedTranslation AS
(
    SELECT id, content, ROW_NUMBER() OVER(PARTITION BY Id ORDER BY lvl DESC) rn
    FROM CTETranslations
)

Выберите из второго cte, где rn = 1, я присоединился к исходной таблице, чтобы показать источник и перевод рядом:

SELECT r.id, s.content, r.content
FROM @T s
JOIN cteNumberedTranslation r
    ON s.Id = r.Id
WHERE rn = 1
ORDER BY Id

Результаты:

id  content                             content
1   Hellö world, I äm text              Hell-1- world, I -4-m text
2   ènd there äré many more chars       -3-nd there -4-r-5- many more chars
3   that are speçial in my dat£base     that are spe-6-ial in my dat-7-base

Обратите внимание, что если ваш контент содержит более 100 специальных символов, вам необходимо добавить подсказку maxrecursion 0 к окончательному выбору:

SELECT r.id, s.content, r.content
FROM @T s
JOIN cteNumberedTranslation r
    ON s.Id = r.Id
WHERE rn = 1
ORDER BY Id
OPTION ( MAXRECURSION 0 );

Смотрите живое демо на rextester.

...