2017-04-18 126 views
15

在我的数据库中我有这个char 。我想通过查询找到它们IN SQL Server数据库

Select * 
from Sometable 
where somecolumn like '%�%' 

这让我没有结果。

我认为这是ANSI编码

+1

是列varchar/char或nvarchar/nchar? – gsharp

+0

您使用的是哪个版本的SQL Server? –

+15

不止一个字符会用represented表示,所有这些字符在代码页上都没有表示。尽管您看到所有这些图形都有相同的图形表示,但它们仍然是不同的字符,它们的比较将返回false。 –

回答

6

这是Unicode replacement character symbol

它可以匹配UCS-2编码中的2,048个无效代码点中的任何一个(或者符号本身的单个字符U+FFFD)。

您可以使用范围和二进制collat​​e子句将它们全部匹配(demo)。

WITH T(N) 
AS 
(
SELECT TOP 65536 NCHAR(ROW_NUMBER() OVER (ORDER BY @@SPID)) 
FROM master..spt_values v1, 
    master..spt_values v2 
) 
SELECT N 
FROM T 
WHERE N LIKE '%[' + NCHAR(65533) + NCHAR(55296) + '-' + NCHAR(57343) + ']%' COLLATE Latin1_General_100_BIN 
+0

我唯一需要改变的就是那些2,048个代码点并不是特别无效的,它们只是需要在某些组合中使用,而不是单独表示任何东西。 –

+0

@srutzky - 我的理解是UCS-2不支持代理对。 –

+0

Martin:是的,UCS-2没有代理对的映射,但所有高位和低位替代码都是为此目的而保留的(以UTF-16实现)。幸运的是,SQL Server是UTF-16(Little Endian),就像.NET和Windows一样。你可以通过执行:SELECT NCHAR(0xD83C),NCHAR(0xDF78),NCHAR(0xD83C)+ NCHAR(0xDF78),NCHAR(0x01F378);'来看到。单独的代码点是没有意义的,但在正确的组合中,它们将正确显示。如果你在一个默认排序规则以'_SC'结尾的数据库中,那么第四个字段将显示该字符而不是NULL。 –

14

使用N-像下面

where col like N'%�%' 

why do you think ,you need N prefix

前缀Unicode字符的字符串常量与字母N不N个前缀,字符串被转换为数据库的默认代码页。此默认代码页可能无法识别某些字符。

感谢马丁·史密斯,此前我有一个字符只测试了早期和它的工作,但马丁指出,它返回所有字符..

下面的查询工作,并返回仅供

select * from #demo where id like N'%�%' 
COLLATE Latin1_General_100_BIN 

演示:

create table #demo 
(
id nvarchar(max) 
) 

insert into #demo 
values 
(N'ﬗ'), 
(N'�') 

知道莫重约unicode的,请参阅以下链接

http://kunststube.net/encoding/

https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/

+1

即使编辑添加了COLLATE选项,这个答案仍然不正确,因为它现在只匹配那个单个字符,但在那里是其他不同的代码点,但会显示有问题的角色。尝试以下查询来查看:'SELECT NCHAR(0xD808),CASE WHEN NCHAR(0xD808)LIKE N'% %'COLLATE Latin1_General_100_BIN2 THEN'YES'ELSE'NO'END;'。 –

5

您可以使用ASCII找出ASCII码为焦炭

Select ascii('�') 

并使用CHAR检索从焦炭该代码并将其组合在一个LIKE表达式中

Select * from Sometable 
where somecolumn like '%'+CHAR(63)+'%' 

请注意您使用的排序规则会影响结果。还取决于您的应用程序用于提供数据的编码(UTF-8,UNICODE等)。还有你如何存储它VARCHAR或NVARCHAR对你所看到的有最后的发言权。

有这个类似的问题更here

编辑 @马克

试试这个简单的测试:

create table sometable(somecolumn nvarchar(100) not null) 
GO 

insert into sometable 
values 
('12345') 
,('123�45') 
,('12345') 
GO 

select * from sometable 
where somecolumn like '%'+CHAR(63)+'%' 
GO 

这仅意味着该字符储存赢得作为“? “在这个测试中。

当您看到一个 时,表示您看到的应用程序不太确定要打印什么。

这也意味着OP可能需要找出什么字符是使用查询。 另外请注意,这意味着像 这样输出的字符串可以由不同的字符组成。 (63)只是一个例子,但你对这个ASCII table将是一个标准的询问。

编辑 @Bridge

不随时间现在就在它深入挖掘,但下面的测试不能奏效

Select ascii('�'), CHAR(ascii('�')), UNICODE(N'�'), CHAR(UNICODE(N'�')) 
GO 

create table sometable(somecolumn nvarchar(100) not null) 
GO 

insert into sometable 
values 
('12345') 
,('123�45') 
,('12345') 
,('12'+NCHAR(UNICODE(N'�'))+'345') 
GO 

select * from sometable 
where somecolumn like '%'+CHAR(63)+'%' 

select * from sometable 
where somecolumn like '%'+NCHAR(UNICODE(N'�'))+'%' 

GO 
+0

'char(63)'是'?',而不是''''。 –

+0

@MarkRotteveel非常贴切,但请参阅我的编辑 – jean

+4

此字符不在ASCII范围内 - 您需要使用'UNICODE'代替。查看运行结果:'select ascii(' '),CHAR(ascii(' ')),UNICODE(N' '),NCHAR(UNICODE(N' '))' – Bridge