3

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

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 列并右键单击,插入列并输入详细信息:

  • 列名 = 供应商代码;
  • 数据类型 = VARCHAR(50);
  • 允许空值 =

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

“供应商”表 - 无法创建索引“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;

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

4

1 回答 1

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
于 2013-09-16T07:54:31.357 回答