繁体   English   中英

如何在SQL Server中删除多个列

[英]How to drop multiple columns in SQL Server

我有多个列

Dbname:dbo.Test

列的名称(示例):

ABC_1 | DEF_2 | GHI_3 | JKL_4 | MNO_5 | PQR_6 | STU_7

如何使用循环编写可以将列GHI_3STU_7查询?

您不需要编写循环来执行此操作,一种方法是使用sys.columns表来获取要删除的所有列。

假设您要删除除“ Col11 ”和“ Col2 ”之外的所有列,在这种情况下,您可以编写如下查询。

declare @dropstmt as nvarchar(max) ='alter table Test  drop column ' 
                          +  stuff((select ', ' + quotename(name) 
             from   
             (
                select c.name 
                from sys.columns c
                    JOIN sys.tables t ON c.object_id = t.object_id
                where t.name = 'test'
                and c.name  not in('col1','col2')
             )t
             for xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, ''); 
print @dropstmt
exec sp_executesql @dropstmt  

作为使用Alter Statement直接删除列的解决方案的替代方法,如果要使用循环,也可以使用游标。

创建一个测试表

Create table testdropcols   
(Col1 varchar(20)
,col2 varchar (30)  
,col3 varchar (30) 
,col4 varchar(30) 
,col5 varchar(30) 
,col6 varchar(30) 
,col7 varchar(30)
,col8 varchar(30)
,col9 varchar(30)
,col10 varchar(30))  

使用systables和syscolumns为当前数据库获取给定表的所有列,并选择几列仅用于测试。

    Declare @tablename varchar(30) , @colname varchar(30), @rownum int 

DECLARE Curstest CURSOR
  for 
select Table_name,columnname,rownum from (
select  st.name as Table_name, sc.name as columnname, Row_number() over (partition by  st.name order by sc.name) rownum   from sys.tables st 
join sys.columns sc on st.object_id = sc.object_id 
where st.name = 'testdropcols'  ) z 
where z.rownum between 5 and 10  
Open Curstest 
Fetch next from Curstest into @tablename, @colname, @rownum 
while @@FETCH_STATUS = 0 
Begin 
declare @sql varchar(max)

set @sql = 'ALTER TABLE '+@tablename+'   Drop column  '+@colname+''

Print @sql 

Exec(@sql)

Print('Dropping column '+ @colname  + ' from ' + @tablename+ ' for rownumber ' +cast(@rownum as varchar(10))) 
Fetch next from Curstest into @tablename, @colname, @rownum 
end 

Close Curstest 
DEALLOCATE Curstest 

使用光标内的print语句,每次执行都会以这种方式获得输出。

  ALTER TABLE testdropcols   Drop column  col4
Dropping column col4 from testdropcols for rownumber 5
ALTER TABLE testdropcols   Drop column  col5
Dropping column col5 from testdropcols for rownumber 6
ALTER TABLE testdropcols   Drop column  col6
Dropping column col6 from testdropcols for rownumber 7
ALTER TABLE testdropcols   Drop column  col7
Dropping column col7 from testdropcols for rownumber 8
ALTER TABLE testdropcols   Drop column  col8
Dropping column col8 from testdropcols for rownumber 9
ALTER TABLE testdropcols   Drop column  col9
Dropping column col9 from testdropcols for rownumber 10

如果选择testdropcols,则将包含drop语句中不存在的列

Col1 Col2 Col3 Col10 

您可以使用此查询从表中删除多个列。

alter table Test
    drop column GHI_3, JKL_4, MNO_5, PQR_6, STU_7

SQL Server中 ,为了删除表的多个列,考虑到列也有约束,这就是你如何做到这一点

alter table dbo.Test
    drop column GHI_3, STU_7

句法:

DROP { [ CONSTRAINT ] constraint_name | COLUMN column_name } [ ,...n ] 

并且不需要在循环中执行此操作,它可以在单个语句中完成。

添加这个因为其他答案实际上没有使用循环。 我不知道你会使用多少次这样的东西......它肯定可以改进

USE Dbname;
go
CREATE PROCEDURE DeleteColumnRange
    @table_name varchar(100),
    @first varchar(100),
    @last varchar(100)
AS   
    SET NOCOUNT ON
    declare @range_start int
    declare @range_end int

    SELECT ORDINAL_POSITION, COLUMN_NAME INTO #columns_to_delete
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME LIKE @table_name

    set @range_start = (SELECT ORDINAL_POSITION
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME LIKE @table_name AND COLUMN_NAME LIKE @first)

    set @range_end = (SELECT ORDINAL_POSITION
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME LIKE @table_name AND COLUMN_NAME LIKE @last)

    DECLARE @result NVARCHAR(max)

    IF @range_end > @range_start
        DECLARE @cnt INT = @range_start

        WHILE @cnt < @range_end
        BEGIN
            SET @cnt = @cnt + 1
            SET @result = (SELECT COLUMN_NAME from #columns_to_delete where ORDINAL_POSITION = @cnt)
            print ('ALTER TABLE ' + @table_name + ' DROP COLUMN ' + @result)
        END;
GO 

用法:

DeleteColumnRange @table_name = 'Test', @first = 'GHI_3', @last = 'STU_7'

返回:

ALTER TABLE Test DROP COLUMN JKL_4
ALTER TABLE Test DROP COLUMN MNO_5
ALTER TABLE Test DROP COLUMN PQR_6

只需复制和执行,比删除列更安全。

我提供了一个示例脚本来删除表中的列列表。 您不需要循环,因为您可以删除单个DROP COLUMN语句中的多个列。

USE tempdb
go

CREATE TABLE dbo.test(a int, b int, c int)

DECLARE @TableName SYSNAME = N'dbo.test' -- table holding columns to drop
DECLARE @ColumnNames NVARCHAR(4000) = N'b,c' -- columns to drop
DECLARE @sqlDropColumnStmt NVARCHAR(4000)
SET @sqlDropColumnStmt = N'ALTER TABLE ' + @TableName + N' DROP COLUMN ' + @ColumnNames;
EXEC(@sqlDropColumnStmt)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM