【发布时间】:2015-10-01 08:18:05
【问题描述】:
这是我的桌子:
CREATE TABLE [dbo].[TestTable]
(
[Name1] varchar(50) COLLATE French_CI_AS NOT NULL,
[Name2] varchar(255) COLLATE French_CI_AS NULL,
CONSTRAINT [TestTable_uniqueName1] UNIQUE ([Name1]),
CONSTRAINT [TestTable_uniqueName1Name2] UNIQUE ([Name1], [Name2])
)
ALTER TABLE [dbo].[TestTable]
ADD CONSTRAINT [TestTable_uniqueName1]
UNIQUE NONCLUSTERED ([Name1])
ALTER TABLE [dbo].[TestTable]
ADD CONSTRAINT [TestTable_uniqueName1Name2]
UNIQUE NONCLUSTERED ([Name1], [Name2])
GO
ALTER INDEX [TestTable_uniqueName1]
ON [dbo].[TestTable]
DISABLE
GO
我的想法是根据客户应用程序启用/禁用一个或其他独特的约束。通过这种方式,我可以在我的 c# 代码中捕获抛出的异常,并向 GUI 显示特定的错误消息。
现在,我的问题是更改列 Name1 和 Name2 的排序规则,我需要使它们区分大小写 (French_CS_AS)。要更改这些字段,我必须删除这两个约束并重新创建它。根据解释的架构,我无法创建启用的约束然后禁用它,因为对于某些客户,我有一个或其他约束的重复键。
对于我的更新脚本,我的想法 1 是
- 将已启用约束的名称保存在临时表中
- 放弃约束
- 更改列
- 创建DISABLED唯一约束
- 根据点 1 中保存的值启用特定约束。
我的问题在第 4 点,我找不到如何使用 ALTER TABLE 语句创建禁用的唯一约束。是否可以直接在sys.indexes表中创建?
我的想法 2 是
- 将 TestTable 重命名为 TestTableCopy
- 使用新字段排序规则重新创建 TestTable,否则使用相同的架构(索引、FK、触发器...)
- 在 TestTable 中禁用特定的唯一约束
- 将数据从 TestTableCopy 迁移到 TestTable
- 删除 TestTableCopy
这样,我担心会失去与其他表/依赖项的一些链接,因为它是我数据库中的中心表。
还有其他方法可以实现我的目标吗?
如有必要,我可以使用唯一索引而不是唯一约束。
【问题讨论】:
-
为什么不能忘记 Unique 约束,在向表中添加记录时检查自己并捕获异常?
-
因为可以通过多种方式插入记录(使用 t-sql,从我的 c# 应用程序,...)。我希望数据库检查我的数据。
-
创建一个存储过程来将记录插入到表中,您可以将它用于您需要的所有类型的插入。在存储过程中根据您的需要检查约束。我会这样做。更改表格不是一个好习惯。
-
所以我需要另一个存储过程来编辑我的行...这种方式我不喜欢 100%。为什么更改表不是最佳实践?无论哪种方式,我都需要一个更改表来更改我的 varchar 列的长度...
-
看看我的例子。
标签: tsql sql-server-2008-r2 unique-constraint unique-index