我有多列
数据库名称:dbo.Test
列名(示例):
ABC_1 | DEF_2 | GHI_3 | JKL_4 | MNO_5 | PQR_6 | STU_7
如何编写使用循环将列GHI_3
删除到STU_7
的查询?
答案 0 :(得分:3)
您无需编写循环来执行此操作,一种方法是使用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
答案 1 :(得分:1)
作为使用Alter语句直接删除列的解决方案的替代方法,如果要使用循环,也可以使用游标。
创建测试表
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
答案 2 :(得分:0)
您可以使用此查询从表中删除多列。
alter table Test
drop column GHI_3, JKL_4, MNO_5, PQR_6, STU_7
答案 3 :(得分:0)
在 SQL Server 中,如果要考虑到列也有约束的情况下删除表的多列,这是怎么做的
alter table dbo.Test
drop column GHI_3, STU_7
语法:
DROP { [ CONSTRAINT ] constraint_name | COLUMN column_name } [ ,...n ]
并且无需循环执行此操作,它可以在单个语句中完成。
答案 4 :(得分:0)
添加此内容是因为其他答案实际上并未使用循环。 我不知道您会用多少次这样的东西... 当然可以改善
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
只需复制和执行,比删除列更安全。
答案 5 :(得分:0)
我提供了一个示例脚本,用于从表中删除列列表。您不需要循环,因为您可以在单个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)