【问题标题】:Drop multiple columns using subquery within alter table在 alter table 中使用子查询删除多个列
【发布时间】:2015-12-08 07:07:53
【问题描述】:

我需要从表中删除除少数列之外的所有列,而我事先不知道这些列的编号和名称。我想从 sys.columns 获取列名,然后删除除少数之外的所有列。我需要这样的东西:

alter table Table
drop column (
            select a.name as ColumnName 
            from sys.all_columns a
            INNER JOIN sys.tables b
            on a.object_id = b.object_id
            where b.name = 'Table'
            where a.name NOT IN (
                                     RowID, 
                                     RemoteUserId, 
                                     Email, 
                                     FirstName, 
                                 )
            )

【问题讨论】:

  • 我认为不动态创建 alter table ddl 语句是不可能的。
  • 一次只能删除一列。如果有很多列,不想单独编写语句,可以使用动态 SQL 来构建它们。
  • 您可以创建一个临时表,将所有数据泵入其中,删除该表并重命名临时表以匹配删除的表。或者您可以只进行查询以创建许多删除列语句
  • 您确定您的操作方式正确吗?也许只是运行 select 'alter table xxx drop column ' + name from sys.columns ... 然后手动运行语句就足够了

标签: sql-server tsql subquery alter-table


【解决方案1】:

首先您需要创建一个Function 以将Comma Separated Strings 拆分为Rows

CREATE FUNCTION [dbo].[FnSplit]
(
@List nvarchar(2000),
@SplitOn nvarchar(5)
)  
RETURNS @RtnValue table 
(

Id int identity(1,1),
Value nvarchar(100)
) 
AS  
BEGIN
While (Charindex(@SplitOn,@List)>0)
Begin 
Insert Into @RtnValue (value)
Select
Value = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1))) 
Set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List))
End 

Insert Into @RtnValue (Value)
Select Value = ltrim(rtrim(@List))
Return
END
GO

然后在Stored Procedure下面创建

 Create Procedure DropColumnExceptGivn
 @table  varchar(50),
 @Column Varchar(max)
 AS
 BEGIN
 SET NOCOUNT ON;
      declare @variables AS TABLE (cols varchar(max))
      declare @sql varchar(max) = ''
      declare @sql1 varchar(max) = ''
      declare @cols nvarchar(max) =''


  set @sql1 = 'SELECT Stuff((select '',''+ Column_name '+'from INFORMATION_SCHEMA.COLUMNS where 
            table_name = ' +''''+@table+''''+
            ' and column_name not in (SELECT Value FROM dbo.FnSplit('+''''+@column+''''+','','')) 
            for xml path('''')),1,1,'''')'
  print @sql1

  insert into @variables
  exec (@sql1)  
  select @cols = cols  from @variables 
  select @cols 

  set @sql= 'alter table '+ @table + ' drop column ' + @cols 

  print @sql 

  exec (@sql)
  end

  go

--创建样本表

Create table pets1 (petid int, PetTypeID int, PetName Varchar(20),OwnerId int)
go

然后执行下面的Stored Procedure. 参数是: 1. 表名 2. 列需要保留(逗号分隔值)

exec DropColumnExceptGivn 'pets1','PetID, PetTypeID'

go
select *from pets1

希望这会有所帮助

【讨论】:

  • 不,我只知道需要留下哪些列。该表不断更新并添加新列。每隔一段时间,我需要删除所有添加的列。
猜你喜欢
  • 2011-09-14
  • 2011-10-10
  • 2019-08-15
  • 2013-04-06
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多