如何以编程方式禁用主键约束?
我有我的MS SQL Server 2005表中的主键的表。我想禁用它。现在我得到的错误:PRIMARY KEY约束 'PK_NAME' 的如何以编程方式禁用主键约束?
冲突。无法在对象'dbo.Table'中插入重复键。
我想这个错误不会发生,并与PRIMARY KEY像正常柱无约束的工作,不是做我更改之后恢复此约束。如何禁用这个约束?
查询我想执行,同时主键约束禁用是复杂的,变化的主键列值。在这个查询的某些点上,当我在主键列中有重复的值时,它会触发这种情况。但在查询结束时,我的所有值都是唯一的。
我不知道很多关于此约束,因为我不是这个表的设计师。我有它的名字,但是现在如果它是集群化的(如此配置)。
没有主键的关系表是非常糟糕的事情。每行必须以某种方式唯一。如果没有候选键被指定为主键,则整行必须是唯一的。
我不知道你为什么要删除主键约束,但我会考虑这样做,不与其他候选键的一个替代它的是,应进行调查红旗。
ALTER TABLE mytable DROP CONSTRAINT PK_Name
要重新启用它:
ALTER TABLE mytable ADD CONSTRAINT PK_Name PRIMARY KEY /* CLUSTERED */ (pk_column)
取消注释CLUSTERED
,如果你希望你的PRIMARY KEY
要群集(即表本身被命令行)
为了弄清楚如果PRIMARY KEY
是群集没有,问题:
EXEC sp_help 'mytable'
并查看返回的6th
结果集。
请勿违反PKEY约束条件。恕我直言,这是最好的解决方案,你将避免重建PKEY的成本,以及如果你不能(重复剩余)?
OR
阅读模式,以了解如何重建PKEY约束,则使用previouly发布的解决方案。
它可能是一个更好的主意,你的整个表SELECT
到一个临时表,执行转换上飞如果可能的话,再拷贝回来。如果不能即时转换,则将简单的整数行索引添加为临时表的主键会容易得多。
要找出主键是什么(假设您的表是dbo。T1):
select si.name as name,
(case when (si.status & 16) > 0 then 1 else 0 end) as isclust,
si.keycnt as keycnt,
si.indid as indid
from sysindexes si
left join sysobjects so on so.id = si.id
where si.indid > 0
and si.indid < 255
and so.xtype <> 'S'
and so.id = OBJECT_ID('dbo.T1')
and (si.status & 2048) > 0
这会给你这样的:
name isclust keycnt indid --------------------------------------------------------------- PK_T1 1 2 1
在这里,你有你的主键的名称(PK_T1),无论是聚集与否,田在其数(2)索引ID(稍后您将需要它)。
下运行以下命令:
select INDEX_COL('dbo.T1', 1, 1) --returns Field1
select INDEX_COL('dbo.T1', 1, 2) --returns Field2
这会给你从索引两个字段的名称。第一个参数是你的表名,第二个是先前获得的索引ID,第三个是从1到keycnt循环(在前一步中返回)。
有了这个信息,你应该能够重建主键如下:
ALTER TABLE dbo.T1 ADD CONSTRAINT PK_T1 PRIMARY KEY CLUSTERED (Field1, Field2)
更新:这可能不会像解析sp_help将结果提到earlier准确(你会错过排序顺序和文件组) ,但更容易编程。
以下为我工作(你必须的db_owner执行此操作)
--Declare一个变量获得表上的约束上,并分配给一个变量
DECLARE @PK_CONST_NAME AS varchar(100)<br>
SET @PK_CONST_NAME = (SELECT NAME FROM SYS.KEY_CONSTRAINTS WHERE OBJECT_NAME(PARENT_OBJECT_ID) = '[TABLENAME]')
- 变量来存储查询
SET @DropAlterQuery = ''<br>
SET @RecreateAlterQuery = ''
- Contruct查询
SET @DropAlterQuery = CONCAT('ALTER TABLE [TABLENAME] DROP CONSTRAINT ',@PK_CONST_NAME)
- 执行对滴速的约束上
EXEC(@DropAlterQuery)
构造查询 - 改变柱尺寸(现在,这个说法可以作为约束上被丢弃)
ALTER TABLE [TABLENAME]
ALTER COLUMN BATCH_ID VARCHAR(200) NOT NULL
- Contruct查询
SET @RecreateAlterQuery = CONCAT(CONCAT('ALTER TABLE [TABLENAME] ADD CONSTRAINT ',@PK_CONST_NAME), ' PRIMARY KEY (<<PRIMARY KEY COLUMN1>>, <<PRIMARY KEY COLUMN2>>, <<PRIMARY KEY COLUMN2>>... So on)')
- 执行了重新创建构建的下降约束上
EXEC(@RecreateAlterQuery)
更改PK值查询:这听起来真的很奇怪!你如何改变应该用于实现表之间关系的值?你确定你正在试图阐述的解决方案是解决你的问题吗? – 2009-04-10 10:20:42
我对这个PK没有任何关系。我知道这听起来很奇怪,也许是这样,但这是我需要在这个地方应用的解决方案。 – 2009-04-10 10:43:04
如果有重复,那么它不再是一个主键,那么为什么将它添加回来呢?你有没有考虑一个连接的主键,可以让你保持约束? – 2009-04-10 11:36:40