Sql server 无法在SQL Server中创建唯一索引,如何知道索引ID引用的是哪个索引

Sql server 无法在SQL Server中创建唯一索引,如何知道索引ID引用的是哪个索引,sql-server,indexing,Sql Server,Indexing,我有一个脚本,执行时会出现错误: Msg 1505,16级,状态1,服务器CBR07I300FVA1,第1行 创建唯一索引已终止,因为为找到了重复的键 索引ID 17。最重要的主键是“44”。 该语句已终止。 脚本包含数千行查询,因此我不知道脚本中的错误来自何处。有没有办法知道“索引ID 17”代表什么?在脚本中的每个重要步骤(例如,创建唯一索引)之前插入print语句,就完成了 通常是这样做的: if @@error <> 0 PRINT '@@error is ' + lt

我有一个脚本,执行时会出现错误:

Msg 1505,16级,状态1,服务器CBR07I300FVA1,第1行
创建唯一索引已终止,因为为找到了重复的键
索引ID 17。最重要的主键是“44”。
该语句已终止。


脚本包含数千行查询,因此我不知道脚本中的错误来自何处。有没有办法知道“索引ID 17”代表什么?

在脚本中的每个重要步骤(例如,
创建唯一索引)之前插入
print
语句,就完成了

通常是这样做的:

if @@error <> 0
   PRINT '@@error is ' + ltrim(str(@@error)) + '.'
else
   print 'Index IX_... successfully created' 
如果@错误0
打印'@@error为'+ltrim(str(@@error))+'
其他的
打印“索引IX”。。。已成功创建'

你说的脚本有几千行,是吗


我的建议是:在中间放置<代码>打印(“测试”)<代码>,看看错误发生在前后。然后在中间的中间等,直到你找到引起你麻烦的地方。

你所做的表格已经包含了数据;而且数据对于你的新索引来说不是唯一的

例如:

 col1 | col2 | col3
====================
 foo  | 1    | q
 bar  | 2    | w
 bar  | 3    | e
 bar  | 2    | r
在上表中,您无法在
(col1,col2)
上创建唯一索引,因为其中的数据是非唯一的(多行
(bar,2)
)。脚本无法知道实际需要哪些“重复”行。有三个选项可供选择:

  • 创建具有重复行的唯一索引(无效,因为它不再是唯一的)
  • 删除重复的行(不安全,它如何知道需要哪些行?)
  • 不执行任何操作并抛出错误(最安全的选项,您在这里)
您可以采取哪些措施来解决此问题:
运行查询以查找重复项-如果按索引使用的列对行进行分组,则某些组将有多行。那些是你的复制品;您需要以某种方式消除它们的重复性。

如果您在SSMS中运行此脚本,只需双击该错误,它就会将您带到导致错误的代码行。

它告诉您:“最重要的主键是:44”-因此,使用pk=44搜索您的行……脚本由许多查询组成。我不知道它指的是哪张桌子。我怎样才能搜索一行?你有没有一个创建唯一索引的部分??如果是这样的话:这很可能是你的罪魁祸首-它试图在什么表和哪些列上创建唯一索引??这是你的问题-找到它,修复它-完成!如果这么简单,我不需要在这里提出问题。运行整个过程需要15分钟以上,除了每次测试时都要恢复数据库。有20多个地方使用createunique索引,其中没有一个引用同一个表。我只想知道答案,以便快速确定错误的来源。我在想索引ID17一定有什么意思,否则如果它没有意义,为什么要在这里使用ID?因为这个问题从来没有直接回答过。。。索引ID仅与特定表相关。因此,表A可以有索引0、2、3和7;表B可以有0、2、3和4。只给出索引ID 2,这还不足以识别特定的索引,因为您仍然需要知道它在哪个表上。谢谢Denis。这是一个选项,但仍然需要回滚所有更改并再次测试。此外,一旦确定原因,我需要删除每个重要步骤的声明。@newguy你为什么要删除它?不知道。我以前没做过。我认为生成输出可能需要更多的时间,所以如果我每天运行20个类似的脚本会怎么样?@newguy除非你将这个
print
语句放入一个while循环中,进行数百万次迭代,否则不会造成任何伤害。如果每个查询都以“创建唯一索引”开始如果使用此语句,则当发生错误时,它们看起来都一样。我仍然不知道错误是从哪里来的。我可能需要计算“createunique INDEX”查询的数量,然后计数以查看错误打印出的位置。所以我认为这不是一个好主意。有没有更好的办法?是的,我知道。问题是我不知道错误所指的是哪个表和哪个索引。@newguy:我误解了这个问题。抱歉。它在消息的右边显示了
第1行
,因此它可能是动态sql。IIRC,一个
GO
会导致行号重置回1,所以这应该仍然有效