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

use*_*076 0 sql sql-server-2008-r2

Select Name from tblAnimal where Id=1
Run Code Online (Sandbox Code Playgroud)

退货:我的宠物

Select Id from tblAnimal where Name='My Pet'  --I copy/pasted this value in SSMS!
Run Code Online (Sandbox Code Playgroud)

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

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

因为这:

Select id from tblAnimal where Name like '%My%'  
Run Code Online (Sandbox Code Playgroud)

返回1而

select id from Animal where Name like '%My %'  
Run Code Online (Sandbox Code Playgroud)

没有回报.

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

Aar*_*and 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;
Run Code Online (Sandbox Code Playgroud)

为了解决有关首先防止这些数据的问题,你肯定可以阻止它,这就是预防应该开始的地方 - 尽可能接近数据,因为你对所有外部方式的控制较少人们可以把垃圾塞进你的桌子.假设你已经有一张桌子:

CREATE TABLE dbo.blat(col VARCHAR(32));
Run Code Online (Sandbox Code Playgroud)

添加约束很简单:

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

现在:

INSERT dbo.blat(col) SELECT NULL;
Run Code Online (Sandbox Code Playgroud)

作品.

INSERT dbo.blat(col) SELECT 'howdy';
Run Code Online (Sandbox Code Playgroud)

作品.

INSERT dbo.blat(col) SELECT 'howdy
    partner';
Run Code Online (Sandbox Code Playgroud)

失败:

消息547,级别16,状态0,行1
INSERT语句与CHECK约束"ck_col_NoCRLF"冲突.冲突发生在数据库"test",表"dbo.blat",列'col'中.
该语句已终止.

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