【问题标题】:Replace specials chars with HTML entities用 HTML 实体替换特殊字符
【发布时间】:2019-03-20 18:33:53
【问题描述】:

我在表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

我现在需要使用 bcp 将这些记录导出到 HTML 文件中:

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 个 replaces,而且它开始看起来很疯狂。

经过大量搜索,我找到了this post which uses a HTML conversion table,但它太高级了,我无法理解:

  1. 该表没有列出特殊字符本身,因为它们在我的文本中(ö, à 等),而是 UnicodeHex。我是否需要将它们添加到表格中才能进行我需要的转换?
  2. 我无法理解如何更新我的脚本以替换所有特殊字符。有人可以给我看一个(伪)代码的 sn-p 吗?

【问题讨论】:

  • 您可以以一种易于理解的方式制作一个简单的表格,其中包含源字符、目标字符等列,并运行一个循环(光标)来执行所有替换操作。这将使您的代码保持整洁,并完成工作。您也可以有 30 个更新行,而不是嵌套。这是你的眼睛糖果,你的规则。
  • 这个答案可能会有所帮助:stackoverflow.com/a/49818394/9395740
  • @MJH 链接中的答案适用于单个字符串,我认为您不能对表格列使用相同的技术。

标签: sql-server tsql sql-server-2012 bcp


【解决方案1】:

使用转换表执行此操作的一种方法是使用递归 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 以便对于每个 id,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 );

See a live demo on rextester.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 2014-11-03
    • 2019-09-23
    相关资源
    最近更新 更多