我们的一个数据库表中有一些数据,其结构是这样的。
ID NAME
1002 Total Cost
1003 Market Price
1004 Total Cost
1005 Total Cost
1006 Sales Price
1007 Gross Price
1008 Gross Price
在我们的用户界面中,有一个页面,您可以在其中看到上表中的不同名称。问题在于,对于“总成本”,我们看到两个记录-一个记录名为“总成本”,另一个记录名为“总成本”(即末尾有一个额外的空间)。我无法确定多余的空间在哪里。
执行以下查询时,无论有多少尾随空格,我总是看到3条记录。
SELECT * FROM AB_MASTER_DATA WHERE NAME LIKE '%Total Cost %'
如何识别不良数据?
我们正在使用MS SQL 2014。
答案 0 :(得分:2)
因此,字符串Total Cost
不会受到普通空格的影响
但是,还有“其他空间”:TAB,硬空间,CR,LF等
而且我们还没有使用nvarchar
在“名称”列上具有UNIQUE约束的示例
DECLARE @UniqueTest table (
ID int NOT NULL IDENTITY (1,1) PRIMARY KEY,
UniqueName varchar(100) NOT NULL UNIQUE
)
--OK so far
INSERT @UniqueTest VALUES ('Market Price')
INSERT @UniqueTest VALUES ('Total Cost')
--gives error
--INSERT @UniqueTest VALUES ('Total Cost ')
--tab
INSERT @UniqueTest VALUES ('Total' + CHAR(9) + 'Cost')
--hard space
INSERT @UniqueTest VALUES ('Total' + CHAR(160) + 'Cost')
-- TRAILING CR
INSERT @UniqueTest VALUES ('Total Cost' + CHAR(13))
SELECT * FROM @UniqueTest
查找不是简单字母数字或空格的行
SELECT * FROM @UniqueTest WHERE UniqueName LIKE '%[^A-Z0-9 ]%'
答案 1 :(得分:0)
问题出在您要添加数据的UI中。 如果要确保尾随空格的安全,则应该对数据进行修剪。但是,您也可能会遇到大写/小写字符串的问题,因此也必须对此进行管理。 您也可以使用
SELECT DISTINCT(*) FROM AB_MASTER_DATA WHERE TRIM(NAME) LIKE 'Total Cost'
要从满足条件的所有对象中仅选择一个:
答案 2 :(得分:0)
UPDATE AB_MASTER_DATA SET NAME = LTRIM(RTRIM(NAME))
注意:您需要确保您的应用程序不INSERT
带有前导或尾随空格。
如果只想SELECT
修剪的数据,可以使用以下内容:
SELECT LTRIM(RTRIM(NAME)) FROM AB_MASTER_DATA
自SQL Server 2017起,您可以使用TRIM
代替LTRIM
和RTRIM
。
答案 3 :(得分:0)
您已经发现,在SQL中的字符串比较中会忽略尾随空格。这是SQL标准的一部分。如果要查找尾随空格,可以执行以下操作:
WHERE CONCAT(NAME, '<') LIKE '%Total Cost <'
重点是在尾随空格后连接一些字符,因此它们不再被忽略。
答案 4 :(得分:0)
您可以使用以下方式识别记录:
where name like 'Total Cost_%'
'_'
是一个通配符,可以匹配任何字符,但是必须有一个字符。
您可以通过执行以下操作来识别字符(如果是ASCII):
select ascii(substring(name, 11, 1))