【问题标题】:Update or replace a special character text in my database field更新或替换我的数据库字段中的特殊字符文本
【发布时间】:2020-04-17 00:21:52
【问题描述】:

我面临无法更新或替换数据库中某些字符的问题。 以下是我检索该文本时在我的列中的样子:

如您所见,“master”和“degree”之间有一个未知字符,我什至无法将其粘贴到此处。

我也尝试更新并用下面的代码替换它(我无法在此处粘贴这两条垂直线,因为它们不受任何浏览器支持,我不确定它们是什么,请参阅上图以查看其中的内容我的 SQL 语句)。

begin transaction
update gm_desc set projdesc=replace(projdesc,'%â  s%','') where projdesc like '%âs%' and proposalno = '15-149-01'

你可以在这里看到真正的 SQL 语句:

我尝试更新或替换它,但我做不到。更新声明成功运行,但我仍然看到奇怪的特殊章程。我将不胜感激。

【问题讨论】:

  • projdescNVarChar 吗?您是否尝试过匹配集合中的字符 not,例如like '%[^a-z0-9]%' 查找行?您可以以十六进制转储列以获取字符值,例如select projdesc, Cast( projdesc as VarBinary(1000) ) as Hex from gm_desc where projectdesc like '%[^a-z0-9 ]%';.
  • 支持HABO的评论:我很确定,这是某种2字节编码的撇号字符,代表“硕士学位” .首先,您应该找出字符串的编码。 VARBINARY(MAX) 的演员表 - 正如@HABO 所建议的那样 - 将帮助您了解内部结构。

标签: sql sql-server tsql sql-server-2016


【解决方案1】:

这是一个标量值函数,它从字符串中删除所有非字母数字字符(保留空格)。

希望对您有所帮助!

dbfiddle

create function dbo.get_alphanumeric_str
(
    @string varchar(max)
)
returns varchar(max)
as
begin

    declare @ret varchar(max);

    with nums as (
        select 1 as n
        union all select n+1 from nums
        where n < 256
    )
    select @ret = replace(stuff(
        (
            select '' + substring(@string, nums.n, 1)
            from nums
            where patindex('%[^0-9A-Za-z ]%', substring(@string, nums.n,1)) = 0 
            for xml path('')
        ), 1, 0, ''
    ), '&#x20;', ' ')
    option (MAXRECURSION 256)

    return @ret;
end

用法

select dbo.get_alphanumeric_str('Helloᶄ âWorld 1234⅊⅐')

返回:Hello World 1234

工作原理

  • nums CTE 仅用于获取数字列表(如果您的字符串较长,您可以将 256 的最大值设置为更高的值;n.b. option (MAXRECURSION n) 用于此 CTE 但必须放置在查询)
  • stuff 本质上是迭代字符串,使用上面的数字列表并提取长度为 1 的子字符串;检查每个字符是否匹配 [^0-9A-Za-z ] 正则表达式组(0-9 所有数字,A-Za-z 所有小写和大写字母,以及单个空格字符)
  • 如果它们匹配,patindex() 应该返回 0;即索引为零。
  • 使用replace(string, '&amp;#x20;', ' ') 作为空格字符,因为xml path 返回特殊编码,请参阅this question
  • 对重音字符使用二进制排序规则;见this answer

【讨论】:

  • 在这种情况下,我很确定,这不会有帮助,至少不是肯定的。假设给定的文本代表 "master's degree",其中 strange characters 是 2 字节编码的撇号。您的函数仅接受 1 字节编码文本 (varchar) 并按原样返回。如果我的假设是正确的,您将不会得到原始文本,而是没有撇号的文本。在其他情况下,您可能会返回其他字符(如果 2 字节代码点的一个字节偶然转换为普通字符)。
  • 非常感谢,我今天会检查一下。感谢您宝贵的时间
猜你喜欢
  • 2014-07-10
  • 2021-06-14
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
  • 2018-10-23
  • 1970-01-01
相关资源
最近更新 更多