在主键上使用 If Not Exists

Posted

技术标签:

【中文标题】在主键上使用 If Not Exists【英文标题】:Using If Not Exists on Primary Key 【发布时间】:2017-11-08 02:53:30 【问题描述】:

我的 sql server 中有一个现有表,我想添加一个聚集在该表列上的主键。我知道语法是:

ALTER TABLE PromotionBenefit  
ADD CONSTRAINT PK_PromotionBenefit2 PRIMARY KEY CLUSTERED (PromotionBenefitCode);  
GO  

问题是该列上已经有一个主键(相同的约束名称)。所以它会抛出一个错误。没事儿。我想知道是否可以在我的查询中添加一个 IF NOT Exists ,这样它就不会引发任何错误。

使用什么语法?

编辑:有没有一种使用这种方式的方法:如果不存在......创建主键集群而不是像上面显示的那样改变表? 可以这样做吗:

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[PromotionBenefit]') AND name = N'idx_EventCode')
CREATE NONCLUSTERED INDEX [idx_EventCode] ON [dbo].[PromotionBenefit]
(
    [EventCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
GO

【问题讨论】:

【参考方案1】:

您必须执行以下操作:

DECLARE @IsPrimary INT

SELECT @IsPrimary=COUNT(1)
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
AND TABLE_NAME = 'PromotionBenefit'

IF @IsPrimary>0
BEGIN
    SELECT 'Table already have Primary Key'
END
ELSE
BEGIN
    ALTER TABLE PromotionBenefit  
    ADD CONSTRAINT PK_PromotionBenefit2 PRIMARY KEY CLUSTERED (PromotionBenefitCode);  
    GO
END

如果你认为,那就试试这个:

IF NOT EXISTS(
SELECT 1
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
AND TABLE_NAME = 'PromotionBenefit')
BEGIN
    ALTER TABLE PromotionBenefit  
    ADD CONSTRAINT PK_PromotionBenefit2 PRIMARY KEY CLUSTERED (PromotionBenefitCode);  
    GO
END

试试这个:

IF NOT EXISTS(SELECT 1 FROM sys.objects WHERE type = 'PK' AND  parent_object_id = OBJECT_ID ('PromotionBenefit'))
BEGIN
    ALTER TABLE PromotionBenefit  
    ADD CONSTRAINT PK_PromotionBenefit2 PRIMARY KEY CLUSTERED (PromotionBenefitCode)
END

希望对你有帮助。

【讨论】:

难道没有更短的方法,比如如果不存在则创建主键? 我可以用 * 代替吗? 另外,为什么我们不能使用“create primary key clustered”而不是alter table? 没问题,可以用* 如果我想创建唯一约束,方法一样吗?【参考方案2】:

一种更短的方式来做预期的事情:

IF OBJECT_ID('idx_EventCode') is null
   CREATE NONCLUSTERED INDEX [idx_EventCode] ON [dbo].[PromotionBenefit] 
   ( [EventCode] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, 
     DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, 
     FILLFACTOR = 80) ON [PRIMARY]
GO

OBJECT_ID 适用于来自 SqlServer 的任何对象,我也使用它来检测表、视图、存储过程的存在...

【讨论】:

这很甜蜜

以上是关于在主键上使用 If Not Exists的主要内容,如果未能解决你的问题,请参考以下文章

使用 IF NOT EXISTS 使用主键和聚类列进行唯一插入

节点的 Sequelize 不允许在主键上自动生成 UUID *除非*字段名称是 'id'

Pandas to_sql 在重复主键上失败

在cassandra的主键上匹配'like'的模式

MySQL 当记录不存在时插入(insert if not exists)

首先使用代码禁用整数主键上的标识(自动递增)