如何删除具有未命名默认值约束和未知索引的列

发布于 2024-08-20 15:02:55 字数 52 浏览 5 评论 0原文

有什么方法可以确定列及其名称以及任何索引的名称是否存在默认约束,以便在删除列之前删除它们?

What is a method of determining if there is a default constraint on a column and its name, and the names of any indexes in order to drop them before dropping the column?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奢望 2024-08-27 15:02:55

以下实用程序将完成该任务。

if (exists (select * from [dbo].sysobjects where (id = object_id(N'[dbo]._spDropDefaultValueConstraint')) and (xtype = 'P')))
 drop procedure [dbo]._spDropDefaultValueConstraint
GO

create procedure [dbo]._spDropDefaultValueConstraint
 @TableName varchar(256),
 @ColumnName varchar(256)
as
/* This proc will drop the default value constraint on
 a column even when you don't know what its name is.
*/
declare @ConstraintName varchar(256)
set @ConstraintName = (
 select 
  dobj.name
 from sys.columns col 
  left outer join sys.objects dobj 
   on dobj.object_id = col.default_object_id and dobj.type = 'D' 
 where col.object_id = object_id('[dbo].'+@TableName) 
 and dobj.name is not null
 and col.name = @ColumnName)

if(isnull(@ConstraintName, '') <> '')
 exec('alter table [dbo].['+@TableName+'] drop constraint ['+@ConstraintName+']')

GO

-------------------------------------------------------------------------------------------

if (exists (select * from [dbo].sysobjects where (id = object_id(N'[dbo]._spDropIndexesForColumn')) and (xtype = 'P')))
 drop procedure [dbo]._spDropIndexesForColumn
GO

create procedure [dbo]._spDropIndexesForColumn
 @TableName varchar(256),
 @ColumnName varchar(256)
as
/* This proc will drop all indexes on a column, both indexes
 and unique constraints as well as multi-part indexes that reference it.
*/
declare @IndexName varchar(256)
declare @IsPrimaryKey bit
declare @IsUniqueConstraint bit

declare crIndexes cursor for
 select
  ind.name, ind.is_primary_key, ind.is_unique_constraint
 from 
  sys.indexes ind
  inner join sys.index_columns ic on ind.object_id = ic.object_id and ind.index_id = ic.index_id
  inner join sys.columns col on ic.object_id = col.object_id and ic.column_id = col.column_id 
  inner join sys.tables t on ind.object_id = t.object_id
 where
  t.name = @TableName and
  col.name = @ColumnName      
open crIndexes
fetch next from crIndexes into @IndexName, @IsPrimaryKey, @IsUniqueConstraint
while(@@fetch_status = 0) begin
 if(@IsPrimaryKey = 1) or (@IsUniqueConstraint = 1)
  exec('alter table [dbo].['+@TableName+'] drop constraint ['+@IndexName+']')
 else
  exec('drop index [dbo].['+@TableName+'].['+@IndexName+']')
 fetch next from crIndexes into @IndexName, @IsPrimaryKey, @IsUniqueConstraint
end
close crIndexes
deallocate crIndexes

GO

-------------------------------------------------------------------------------------------

if (exists (select * from [dbo].sysobjects where (id = object_id(N'[dbo]._spDropColumn')) and (xtype = 'P')))
 drop procedure [dbo]._spDropColumn
GO

create procedure [dbo]._spDropColumn
 @TableName varchar(256),
 @ColumnName varchar(256)
as
/* This proc will drop a column (first dropping the default value
 constraint and any indexes if they exist) if it exists.
*/
if (exists (select * from [dbo].sysobjects where (id = object_id('[dbo].'+@TableName)) and (xtype = 'U'))) and
   (exists (select * from [dbo].syscolumns where (id = object_id('[dbo].'+@TableName)) and (name = @ColumnName))) begin
 exec [dbo]._spDropIndexesForColumn @TableName, @ColumnName
 exec [dbo]._spDropDefaultValueConstraint @TableName, @ColumnName
 exec('alter table [dbo].['+@TableName+'] drop column ['+@ColumnName+']')
end
GO

然后很容易调用,如下所示:

exec [dbo]._spDropColumn 'TableName', 'ColumnName'

我没有查看外键约束,因为我们不使用它们,但也许它们也可以包含在内。

The following utility procs will accomplish the task.

if (exists (select * from [dbo].sysobjects where (id = object_id(N'[dbo]._spDropDefaultValueConstraint')) and (xtype = 'P')))
 drop procedure [dbo]._spDropDefaultValueConstraint
GO

create procedure [dbo]._spDropDefaultValueConstraint
 @TableName varchar(256),
 @ColumnName varchar(256)
as
/* This proc will drop the default value constraint on
 a column even when you don't know what its name is.
*/
declare @ConstraintName varchar(256)
set @ConstraintName = (
 select 
  dobj.name
 from sys.columns col 
  left outer join sys.objects dobj 
   on dobj.object_id = col.default_object_id and dobj.type = 'D' 
 where col.object_id = object_id('[dbo].'+@TableName) 
 and dobj.name is not null
 and col.name = @ColumnName)

if(isnull(@ConstraintName, '') <> '')
 exec('alter table [dbo].['+@TableName+'] drop constraint ['+@ConstraintName+']')

GO

-------------------------------------------------------------------------------------------

if (exists (select * from [dbo].sysobjects where (id = object_id(N'[dbo]._spDropIndexesForColumn')) and (xtype = 'P')))
 drop procedure [dbo]._spDropIndexesForColumn
GO

create procedure [dbo]._spDropIndexesForColumn
 @TableName varchar(256),
 @ColumnName varchar(256)
as
/* This proc will drop all indexes on a column, both indexes
 and unique constraints as well as multi-part indexes that reference it.
*/
declare @IndexName varchar(256)
declare @IsPrimaryKey bit
declare @IsUniqueConstraint bit

declare crIndexes cursor for
 select
  ind.name, ind.is_primary_key, ind.is_unique_constraint
 from 
  sys.indexes ind
  inner join sys.index_columns ic on ind.object_id = ic.object_id and ind.index_id = ic.index_id
  inner join sys.columns col on ic.object_id = col.object_id and ic.column_id = col.column_id 
  inner join sys.tables t on ind.object_id = t.object_id
 where
  t.name = @TableName and
  col.name = @ColumnName      
open crIndexes
fetch next from crIndexes into @IndexName, @IsPrimaryKey, @IsUniqueConstraint
while(@@fetch_status = 0) begin
 if(@IsPrimaryKey = 1) or (@IsUniqueConstraint = 1)
  exec('alter table [dbo].['+@TableName+'] drop constraint ['+@IndexName+']')
 else
  exec('drop index [dbo].['+@TableName+'].['+@IndexName+']')
 fetch next from crIndexes into @IndexName, @IsPrimaryKey, @IsUniqueConstraint
end
close crIndexes
deallocate crIndexes

GO

-------------------------------------------------------------------------------------------

if (exists (select * from [dbo].sysobjects where (id = object_id(N'[dbo]._spDropColumn')) and (xtype = 'P')))
 drop procedure [dbo]._spDropColumn
GO

create procedure [dbo]._spDropColumn
 @TableName varchar(256),
 @ColumnName varchar(256)
as
/* This proc will drop a column (first dropping the default value
 constraint and any indexes if they exist) if it exists.
*/
if (exists (select * from [dbo].sysobjects where (id = object_id('[dbo].'+@TableName)) and (xtype = 'U'))) and
   (exists (select * from [dbo].syscolumns where (id = object_id('[dbo].'+@TableName)) and (name = @ColumnName))) begin
 exec [dbo]._spDropIndexesForColumn @TableName, @ColumnName
 exec [dbo]._spDropDefaultValueConstraint @TableName, @ColumnName
 exec('alter table [dbo].['+@TableName+'] drop column ['+@ColumnName+']')
end
GO

It's then easy to invoke as follows:

exec [dbo]._spDropColumn 'TableName', 'ColumnName'

I haven't looked at foreign key constraints as we don't use them, but perhaps they could be included too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文