由于空格特征,Where子句在SQL中不起作用

时间:2013-01-24 21:21:01

标签: sql sql-server-2008-r2

Select Name from tblAnimal where Id=1

返回:我的宠物

Select Id from tblAnimal where Name='My Pet'  --I copy/pasted this value in SSMS!

返回空的变更集(为什么?)

经过一番研究后,我发现它可以是Char(10)和Char(13)。所以,我想,当我复制My Pet的粘贴时,会自动将Char(10)转换为Space for Windows环境吗?

因为:

Select id from tblAnimal where Name like '%My%'  

返回1 而

select id from Animal where Name like '%My %'  

什么都不返回。

问题。
1.为什么会发生这种情况? 2.如何解决这个问题(生产数据库,数百万条记录)
3.如何防止这种情况发生?

2 个答案:

答案 0 :(得分:6)

要清理数据,请用空格替换CR / LF对:

UPDATE dbo.table
  SET column = REPLACE(REPLACE(column, CHAR(10), ''), CHAR(13), ' ')
  WHERE CHARINDEX(CHAR(10), column) + CHARINDEX(CHAR(13), column) > 0;

为了解决关于首先阻止这一数据的观点,你肯定会阻止它,这就是预防应该开始的地方 - 尽可能接近尽可能的数据,因为你对人们可以将垃圾填入表中的所有外部方式的控制较少。假设你已经有一张桌子:

CREATE TABLE dbo.blat(col VARCHAR(32));

添加约束很简单:

ALTER TABLE dbo.blat ADD CONSTRAINT ck_col_NoCRLF
  CHECK(CHARINDEX(CHAR(10), col) + CHARINDEX(CHAR(13), col) = 0);

现在:

INSERT dbo.blat(col) SELECT NULL;

作品。

INSERT dbo.blat(col) SELECT 'howdy';

作品。

INSERT dbo.blat(col) SELECT 'howdy
    partner';

失败:

  

Msg 547,Level 16,State 0,Line 1
INSERT语句与CHECK约束冲突" ck_col_NoCRLF"。冲突发生在数据库" test",table" dbo.blat",column' col'。
  声明已经终止。

您可能还会考虑添加各种其他特殊字符 - CHAR(9) tab )也是常见字符。

答案 1 :(得分:1)

char 10和char 13是换行符和回车符 - 它们不是空格,即使它们在网格结果上显示为这样。如果您在SSMS中查看结果,最好告诉它以文本(ctrl + T或工具栏上)查看结果。如果你这样做,你会看到结果是否真的:

My Pet

或者

My
Pet

Grid的结果会在一行显示为My Pet,因为这就是网格的工作原理。结果为文本将显示新行,即使是单个记录,因此您可以更好地查看表中的数据。