【问题标题】:Write a T-SQL query that filters records containing NCHAR(2028)编写一个 T-SQL 查询来过滤包含 NCHAR(2028) 的记录
【发布时间】:2010-02-02 19:45:04
【问题描述】:

我的最终目标是编写一个 sql 脚本,从特定表中选择数据,其中 nvarchar(max) 列包含字符 NCHAR(2028)。

但显而易见:

select * 
from tablename
where columnname like '%' + NCHAR(2028) + '%'

返回所有行。

【问题讨论】:

  • columnname的数据类型是什么?
  • 数据类型为nvarchar(128)

标签: sql sql-server sql-server-2005 tsql


【解决方案1】:

使用二进制排序规则进行相似比较。

select * 
from tablename
where columnname COLLATE Latin1_General_Bin like '%' + NCHAR(2028) + '%'

【讨论】:

    【解决方案2】:

    这行得通

    CREATE TABLE #temp (columnname NVARCHAR(128))
    
    INSERT #temp VALUES ('a')
    INSERT #temp VALUES ( NCHAR(2028))
    INSERT #temp VALUES ('b')
    INSERT #temp VALUES ('c' +  NCHAR(2028) + 'c')
     INSERT #temp VALUES ('a' + NCHAR(2028) + 'b') 
    
    
    
    
    
     SELECT  *
    FROM #temp
    WHERE ColumnName COLLATE Latin1_General_Bin Like N'%' + NCHAR(2028) + '%'
    
    drop table  #temp
    

    【讨论】:

    • 检查参数顺序,你最后的查询不应该是这样的:CHARINDEX(NCHAR(2028), columnname)
    • 已修复...我认为 '%' 会把它扔掉...也许 RegEx 无法处理这些字符...
    • 不幸的是,这对我的情况没有帮助。当#temp 中的行包含多个字符时,即:INSERT #temp VALUES ('a' + NCHAR(2028) + 'b')
    • 迈克尔,你只需要尾随的 %:LIKE N'%' + NCHAR(2028) + '%'; ...实际上你根本不需要 N 前缀,我检查了计划,没有 CONVERT_IMPLICIT 需要担心。
    • 丹尼斯,你为什么要改变它? COLLATE 版本有效,不需要繁琐的 PATINDEX 或 OR - 只需要尾随 +'%'。我不明白为什么您的 PATINDEX 可以工作,但不能: WHERE patindex('%' + NCHAR(2028) +'%', columnname) > 0 - 这会返回所有行。
    【解决方案3】:

    我认为您在排序之外的字符上遇到了限制。我有一些奇怪的行为。注意这里两个 SELECT 的结果:

    CREATE TABLE dbo.foo
    (
        id INT IDENTITY(1,1),
        bar NVARCHAR(128)
    );
    
    INSERT dbo.foo(bar) SELECT N'foobar'
    UNION 
    SELECT N'foo' + NCHAR(2028) + N'bar'
    
    SELECT *
        FROM dbo.foo
        WHERE bar LIKE N'%' + NCHAR(2028) + '%';
    
    TRUNCATE TABLE dbo.foo;
    
    INSERT dbo.foo(bar)
    SELECT N'foo' + NCHAR(2028) + N'bar'
    
    SELECT *
        FROM dbo.foo
        WHERE bar LIKE N'%' + NCHAR(2028) + '%';
    
    DROP TABLE dbo.foo;
    

    请注意,无论我们插入一行还是两行,我们总是会取回第一行,即使查询相同且数据已更改。

    不幸的是,将 NCHAR(2028) 的实际值粘贴到 SSMS 中不起作用,因为它不在支持的字符集中(我在超级马里奥兄弟中得到一个像问号框一样的字形)。否则我只会建议:

    WHERE columnname LIKE N'%߬%';
    

    如果您可以从您的代码中做到这一点(而不用担心 SSMS),它可能是一个可行的替代方案。

    【讨论】:

    • PS 我意识到我的最后一行代码显示了一个尼娜口音或其他东西,这可能不是你所期望的。想象一下,您将 NCHAR(2028) 的实际字符表示粘贴到代码中,看看这是否有助于从应用程序端解决它。
    • 这就是为什么每个人都应该学习并且只使用世界语,我们会消除所有这些东西
    • 我正在消化这条评论。我注意到第一个 UNION 不是 UNION ALL ,因此插入了一行。 (不知何故,UNION 确定两个字符串相同)
    • 另请注意,SQL Server(至少在默认 SQL 排序规则中)将大多数值 > NCHAR(384) 视为未知,将它们转换为问号。试试这个: SELECT NCHAR(ASCII(NCHAR( 384 (with a few exceptions), and any number greater than 1642>)));
    • 你说得对,迈克尔......似乎 SQL Server 忽略了这个字符。如果您使用 UNION ALL 运行查询,您将在第一个查询中得到两行,我的错。然而,虽然字符串被认为是相同的,但结果显示其中有 is 一个字符。它只是看起来不同,具体取决于您是使用结果到文本还是结果到网格。
    猜你喜欢
    • 1970-01-01
    • 2014-02-14
    • 2020-09-15
    • 2022-01-09
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多