2015-07-13 91 views
2

这是我的表:创建唯一约束最初禁用

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 

我的想法是使/取决于客户应用禁用一个或其他唯一contraint。通过这种方式,我可以捕捉到我的c#代码中抛出的异常,并向GUI显示特定的错误消息。现在

,我的问题是改变列Name1 & Name2的整理,我需要让他们区分大小写(French_CS_AS)。要改变这些字段,我必须删除这两个约束并重新创建它。根据解释的模式,我不能创建一个启用的约束,然后禁用它,因为有些客户,我有一个或其他约束的重复键。

对于我的更新脚本,我的想法号码1是

  1. 保存在临时表
  2. 降启用的约束的约束
  3. 阿尔特列
  4. 创建禁用唯一约束名称
  5. 根据保存的值以点1启用特定约束。

我的问题是在第4点,我找不到如何使用ALTER TABLE语句创建禁用的唯一约束。是否有可能直接在sys.indexes表中创建它?

我的想法号2是

  1. 重命名TestTable的到TestTableCopy
  2. 重新创建TestTable的新栏整理,否则相同的架构(索引,FK,触发器,...)
  3. 禁用在TestTable的特异性目的唯一约束上
  4. 从TestTableCopy数据迁移到TestTable的
  5. 降TestTableCopy

以这种方式,我担心的是松散与其他表/相关性的链接,因为它是我数据库中的中心表。

有没有其他办法可以实现我的目标?

如有必要,我可以使用唯一索引而不是唯一约束。

+0

为什么不能忘记Unique约束并检查自己并在向表中添加记录时捕获异常? – CiucaS

+0

因为可以从多种方式插入记录(使用t-sql,从我的c#应用程序中...)。我希望数据库检查我的数据。 – stephanejulien

+0

创建存储过程以将记录插入到表中,可以将它用于所有需要的插入类型。在存储过程中,根据需要检查约束。那将是我会这样做的方式。改变表格不是一个好习惯。 – CiucaS

回答

1

看起来不可能在已具有重复值的列上创建唯一索引。

所以,而不是具有禁用唯一索引或者:

  • 不具有索引(此时是与具有从视查询处理器点禁用指数),
  • 或创建一个非唯一索引。

对于那些您的客户拥有唯一数据的实例创建唯一索引。对于那些客户拥有非唯一数据的实例,可以创建非唯一索引。

+0

你是对的!我以许多方式搜索,无法创建禁用的唯一约束或禁用的唯一索引。我的解决方案是放弃我的约束,改变我的列,并只重新创建最初启用的那些。 – stephanejulien

0
CREATE PROCEDURE [dbo].[spUsers_AddUsers] 
@Name1 varchar(50) , 
@Name2 varchar(50) , 
@Unique bit 
AS 

declare @err int 
begin tran 
    if @Unique = 1 begin 
if not exists (SELECT * FROM Users WHERE Name1 = @Name1 and Name2 = @Name2) 
begin 
    INSERT INTO Users (Name1,Name2) 
    VALUES (@Name1,@Name2) 
    set @err = @@ERROR 
end else 
begin 
    UPDATE Users 
    set Name1 = @Name1, 
    Name2 = @Name2 
    where Name1 = @Name1 and Name2 = @Name2 
    set @err = @@ERROR 
end 

end else begin 
    if not exists (SELECT * FROM Users WHERE Name1 = @Name1) 
    begin 
     INSERT INTO Users (Name1,Name2) 
     VALUES (@Name1,@Name2) 
     set @err = @@ERROR 
    end else 
    begin 
    UPDATE Users 
    set Name1 = @Name1, 
     Name2 = @Name2 
    where Name1 = @Name1 
    set @err = @@ERROR 
end 


if @err = 0 commit tran 
    else rollback tran 

因此,首先检查是否需要唯一的Name1和Name2或Name1。然后,如果你根据你的限制进行插入/更新。

+0

我了解你的方法,但只有在我无法更改我的表时才会考虑。我的所有数据库都设计有限制,我认为这不是一个坏方法。 – stephanejulien

+0

事实并非如此,我一直都在使用约束条件,并且它们在每个数据库中都是非常重要的部分,但是您的情况似乎有些过时,并且我从来没有遇到它(每次都必须更改约束条件)。 – CiucaS