Sql server 在alter table中使用子查询删除多个列

Sql server 在alter table中使用子查询删除多个列,sql-server,tsql,subquery,alter-table,Sql Server,Tsql,Subquery,Alter Table,我需要删除表中的所有列,但只有少数列,而我事先不知道这些列的数量和名称。我想从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_i

我需要删除表中的所有列,但只有少数列,而我事先不知道这些列的数量和名称。我想从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, 
                                 )
            )

首先,您需要创建一个
函数
,将
逗号分隔的字符串
拆分为

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
然后在下面创建
存储过程

 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
然后执行下面的
存储过程。
这些参数是:1。表名2。列需要保留(逗号分隔的值)


希望这会有所帮助

首先,您需要创建一个
函数
来将
逗号分隔字符串
拆分为

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
然后在下面创建
存储过程

 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
然后执行下面的
存储过程。
这些参数是:1。表名2。列需要保留(逗号分隔的值)


希望这会有所帮助

我认为不动态创建alter table ddl语句是不可能的。一次只能删除一列。如果有许多列,并且您不想单独编写语句,则可以使用动态SQL来构建它们。您可以创建临时表,将所有数据注入临时表,删除该表,然后重命名临时表以匹配删除的临时表。或者,您可以通过查询创建多个drop columns语句。您确定您的操作方式正确吗?可能只是从sys.columns运行select'altertable xxx drop column'+name。。。如果不动态创建alter table ddl语句,手动运行这些语句是不够的。一次只能删除一列。如果有许多列,并且您不想单独编写语句,则可以使用动态SQL来构建它们。您可以创建临时表,将所有数据注入临时表,删除该表,然后重命名临时表以匹配删除的临时表。或者,您可以通过查询创建多个drop columns语句。您确定您的操作方式正确吗?可能只是从sys.columns运行select'altertable xxx drop column'+name。。。然后手动运行语句就足够了不,我只知道需要留下哪些列。该表将不断更新,并添加新列。每隔一段时间,我需要删除所有添加的列。不,我只知道哪些列需要保留。该表将不断更新,并添加新列。每隔一段时间,我需要删除所有添加的列。