Sql WHERE子句禁止重复行

Sql WHERE子句禁止重复行,sql,sql-server-2008,sql-server-2008-r2,Sql,Sql Server 2008,Sql Server 2008 R2,当主键位于新表上时,由于主键约束,我遇到了表复制错误问题。通过不设置主键进行一些调查,我在源表中找到了一个重复的行,仍然不确定它是如何进入的,但我更好奇的是我发现的其余部分 下面是: 我有一个选择完整表并返回以下内容的SQL查询: SELECT * FROM search_term_suggest order by search_term 你可以看到这个值是重复的,我必须在表格中滚动才能找到它 但当我将我的查询限制为: SELECT * FROM search_term_suggest

当主键位于新表上时,由于主键约束,我遇到了表复制错误问题。通过不设置主键进行一些调查,我在源表中找到了一个重复的行,仍然不确定它是如何进入的,但我更好奇的是我发现的其余部分

下面是:

我有一个选择完整表并返回以下内容的SQL查询:

SELECT *
 FROM search_term_suggest
 order by search_term
你可以看到这个值是重复的,我必须在表格中滚动才能找到它

但当我将我的查询限制为:

SELECT *
 FROM search_term_suggest
 where search_term = 'b'
您可以看到它过滤掉了第一个值。数据库上没有触发器,或者我看到的任何东西都不会限制select查询

我正在运行SQL2008R2。非常感谢您的帮助。我将表复制到的数据库是一个SQL 2000数据库,当使用与上面相同的查询进行选择时,我会得到预期的结果


编辑:search\u term是一个varchar(100),search\u term\u suggest是一个表而不是一个视图。

可能是因为在29645行中,search\u term值不是'b',而是'b'(即b后跟空格)

我猜:
search\u term
是一个
字符/NCHAR
,后面有空格(或出于其他原因正在考虑使用尾随空格)。请尝试:

您可能还需要消除不受修剪操作影响的制表符/回车符

WHERE LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(search_term,
  CHAR(9), ''), CHAR(10), ''), CHAR(13), ''))) = 'b';
请注意,上述两个查询都不允许使用索引,因此如果
search\u term
上有索引,您可能应该在将列更改为
varchar
nvarchar
并确保填充设置和空白不会导致问题后重新生成索引

其他猜测:正如@Dems所指出的,检查第一个查询中两列的长度。同时尝试将where子句更改为以下内容,仅用于调查目的:

WHERE search_term LIKE 'b%'
  AND LEN(search_term) > 1;
如果你在那里得到任何结果,那么你可以说:

DECLARE @val VARCHAR(100), @i INT;

DECLARE c CURSOR LOCAL STATIC READ_ONLY FAST_FORWARD 
  FOR SELECT search_term FROM dbo.search_term_suggest
  WHERE search_term LIKE 'b%'
    AND LEN(search_term) > 1;

OPEN c;

FETCH NEXT FROM c INTO @val;

WHILE @@FETCH_STATUS = 0
BEGIN
  SET @i = 1;
  PRINT '-----' + @val + ' (' + RTRIM(LEN(@val)) + ')';
  WHILE @i <= LEN(@val)
  BEGIN
    PRINT SUBSTRING(@val, @i, 1) + ' = ' + ASCII(SUBSTRING(@val, @i, 1));
    SET @i = @i + 1;
  END

  FETCH NEXT FROM c INTO @val;
END
CLOSE c;
DEALLOCATE c;
声明@val VARCHAR(100),@i INT;
声明c游标本地静态只读快进
从dbo中选择搜索项。搜索项建议
在哪里搜索像“b%”这样的词
LEN(搜索项)>1;
开放式c;
从c取下一个到@val;
而@@FETCH\u STATUS=0
开始
设置@i=1;
打印'----'+@val+'('+RTRIM(LEN(@val))+');

虽然@i它不能是b,但它只是屏幕上看起来像b的东西,特别是在该列上有约束的情况下。如果你将查询结果复制到文本中,你能在文本编辑器中搜索“b”并找到它吗?

搜索词\u建议
表还是视图?
搜索词的数据类型是什么?(触发器是不相关的,因为没有选择触发器。)你能告诉我们运行时结果是什么样的吗:
SELECT*FROM search\u term\u建议search\u term像“b%”这样的搜索词在哪里?@GerardoLima添加like子句会返回两条记录。请参见Aaron答案中的注释。这是一个varchar(100)-抱歉,忘了提到上面的内容-添加RTRIM会得到相同的结果。@Robert-如果添加
LEN(搜索词)作为长度,
对于第一个查询,结果是什么?一行的长度是5,返回的一行的长度是1。这就解释了为什么它只显示1,但为什么RTRIM不显示第二行?所以现在我的问题是,为什么这会导致主键约束?(1)RTRIM不修剪制表符/回车符/换行符。(2) 要发生主键约束冲突,必须将这些值视为等效值。因为我们还不知道其他4个字符是什么,所以我们无法告诉您原因。好的,很酷。我想我有我需要继续的内容。谢谢您的帮助。
DECLARE @val VARCHAR(100), @i INT;

DECLARE c CURSOR LOCAL STATIC READ_ONLY FAST_FORWARD 
  FOR SELECT search_term FROM dbo.search_term_suggest
  WHERE search_term LIKE 'b%'
    AND LEN(search_term) > 1;

OPEN c;

FETCH NEXT FROM c INTO @val;

WHILE @@FETCH_STATUS = 0
BEGIN
  SET @i = 1;
  PRINT '-----' + @val + ' (' + RTRIM(LEN(@val)) + ')';
  WHILE @i <= LEN(@val)
  BEGIN
    PRINT SUBSTRING(@val, @i, 1) + ' = ' + ASCII(SUBSTRING(@val, @i, 1));
    SET @i = @i + 1;
  END

  FETCH NEXT FROM c INTO @val;
END
CLOSE c;
DEALLOCATE c;