SQL Server过滤索引 - 任何人都可以解释我看到的这个错误吗?

时间:2013-08-07 14:18:42

标签: sql sql-server

好的,所以我有一个带过滤索引的表。这是一个用于创建表,添加一些数据然后添加索引的脚本:

CREATE TABLE Supplier (
    SupplierId INT NOT NULL,
    SupplierLinkId INT NULL,
    SupplierName VARCHAR(50));
INSERT INTO Supplier VALUES (1, 2, 'Test Supplier 1');
INSERT INTO Supplier VALUES (2, NULL, 'Test Supplier 2');
INSERT INTO Supplier VALUES (3, NULL, 'Test Supplier 3');
CREATE UNIQUE NONCLUSTERED INDEX uq$Supplier$SupplierLinkId ON Supplier (SupplierLinkId)     WHERE SupplierLinkId IS NOT NULL;

然后我决定在我的表中添加一个新列,比如说供应商代码,并且出于可维护性原因,我不希望它在表的末尾。所以我不能用:

ALTER TABLE Supplier ADD SupplierCode VARCHAR(50);

相反,我进入表设计器,高亮显示SupplierLinkId列并右键单击,插入列并输入详细信息:

  • 列名= SupplierCode;
  • 数据类型= VARCHAR(50);
  • 允许Nulls =

当我点击保存时,我收到此错误:

'供应商'表 - 无法创建索引'uq $ Supplier $ SupplierLinkId' CREATE UNIQUE INDEX语句终止,因为找到了对象名称'dbo.Supplier'和索引名称'uq $ Supplier $ SupplierLinkId'的重复键。重复键值为()。 声明已经终止。

但是这个索引应该被过滤掉,出于某种原因它忽略了过滤器。

如果我试图放弃索引:

DROP INDEX Supplier.uq$Supplier$SupplierLinkId;

...然后回到我仍然开放的桌面设计师,我得到了这个错误:

表'供应商'已更改: - 索引'uq $ Supplier $ SupplierLinkId'已删除,将重新创建。

所以我必须从设计师那里走出来然后再回来进行改变。然后我可以重新创建我的索引(首先应该不是问题)。

但后来我决定我希望新的“供应商代码”列不可为空,所以我在设计器中更改它...并获得有关具有重复值的索引的相同错误。相反,我用以下方式编写了这个工作的脚本:

ALTER TABLE Supplier ALTER COLUMN SupplierCode VARCHAR(50) NOT NULL;

现在我可以理解,如果在打开表时对表进行了更改,那么表设计者可能不喜欢它,这是非常容易理解的。我不明白为什么我不能使用表设计器对我的表进行更改而不会得到关于我的过滤索引具有重复值的虚假错误,当它显然没有。

1 个答案:

答案 0 :(得分:0)

我还想重新排序新的数据库列以便于阅读,以帮助那些可怜的未来开发者和跟我来的dbas。毕竟,在成熟的应用程序中,40% - 90%的时间将用于返工和不断变化的要求。

但是,Microsoft不同意,因此没有列重新排序SQL,但如果您愿意浪费时间,可以在Microsoft Connect上投票。他们更喜欢使用临时表并重新创建表格,如下所示......

--rename table to free up the name
EXEC sp_rename 'Supplier', 'Supplier_backup'
GO

--create the table again with the new column in the order that you like
CREATE TABLE Supplier (
    SupplierId INT NOT NULL,
    SupplierCode VARCHAR(50),
    SupplierLinkId INT NULL,
    SupplierName VARCHAR(50))
GO

--copy the data back in 
INSERT INTO Supplier (SupplierId,SupplierCode,SupplierLinkId,SupplierName)
SELECT SupplierId,NULL,SupplierLinkId,SupplierName
FROM Supplier_backup
GO

--add the index
CREATE UNIQUE NONCLUSTERED INDEX uq$Supplier$SupplierLinkId ON Supplier (SupplierLinkId)     
WHERE SupplierLinkId IS NOT NULL
GO

--cleanup the old table
DROP TABLE Supplier_backup
GO