如果从列表中存在列,则如何从SQL Server临时表中删除列?
类似的东西:
DECLARE @cols AS NVARCHAR(MAX)
@cols will have value like [first_name], [last_name], .....
So @cols = '[first_name], [last_name], .....'
现在
ALTER TABLE #my_tables
DROP COLUMN @cols
如何检查#my_tables
是否包含last_name
?如果不是忽略它而不是抛出错误。我仍然需要删除@cols中存在的其他列
我认为如果各列上存在条件,我们可以这样做。
由于
答案 0 :(得分:3)
我同意CRAFTY DBA:您应该将这些值作为表值参数传递,而不是以逗号分隔列表。但这并没有真正改变问题:您仍然要动态生成所有DROP COLUMN
命令,无论是使用表值函数从CSV解析列名,还是从TVP中提取。
我将继续您目前对逗号分隔列表的要求。
首先,创建一个字符串拆分功能。这是我使用的那个:
CREATE FUNCTION [dbo].[SplitString]
(
@List NVARCHAR(MAX),
@Delim VARCHAR(255)
)
RETURNS TABLE
AS
RETURN ( SELECT [Value] FROM
(
SELECT
[Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number],
CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number])))
FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_objects) AS x
WHERE Number <= LEN(@List)
AND SUBSTRING(@Delim + @List, [Number], LEN(@Delim)) = @Delim
) AS y
);
GO
现在,创建一个愚蠢的#temp表:
CREATE TABLE #foo(id INT, x INT);
现在,您可以声明要尝试删除的列的列表,创建一个动态SQL语句,在删除它们之前检查它们是否存在,然后删除它们可以执行的操作:
DECLARE @cols VARCHAR(MAX);
SET @cols = '[first_name], [last_name], [id]';
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';
SELECT @sql = @sql + N'IF EXISTS (SELECT 1 FROM tempdb.sys.columns AS c
WHERE [object_id] = OBJECT_ID(''tempdb..#foo'')
AND name = ' + REPLACE(REPLACE(QUOTENAME(s.Value, ''''),']',''),'[','') + ')
ALTER TABLE #foo DROP COLUMN ' + s.Value + ';'
FROM dbo.SplitString(@cols, ',') AS s;
EXEC sp_executesql @sql;
SELECT * FROM #foo; -- this only returns the column x
如果再次运行这部分代码,对同一个表运行,它将无误地运行。您可能遇到的一些错误是:
答案 1 :(得分:1)
您可以使用动态SQL;但请注意SQL注入。
我会将@cols作为参数传递给存储过程。
程序正文如下。
-- Declare local variables
DECLARE @STMT NVARCHAR(MAX);
-- Create the stmt
SET @STMT = 'ALTER TABLE #my_tables DROP COLUMN ' + @cols;
-- Execute the stmt
EXEC sp_executesql @STMT;
我宁愿传递一个表值参数,但这只是我。
答案 2 :(得分:1)
检查你需要记住的临时表的列,它存储在temp db
中select *
from tempdb.sys.columns
where object_id = object_id('tempdb..#my_tables')
答案 3 :(得分:0)
使用此:
SELECT *
FROM information_schema.COLUMNS
WHERE
TABLE_SCHEMA = 'db_name'
AND TABLE_NAME = 'table_name'
AND COLUMN_NAME = 'column_name'
它将返回列是否存在,使用此SQL的响应来决定是否执行删除