我狡猾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
如果再次運行這部分代碼,對同一個表,它會運行沒有錯誤。您可能遇到的一些錯誤是:
- 如果您嘗試刪除參與任何約束(默認,PK,FK,檢查等)的列。
- 如果您嘗試刪除表中的最後一列。
- 如果您的列名稱選擇非常差,以某種方式繞過了我試圖在此列入的所有保護措施。
你爲什麼要麻煩從#temp表中刪除列?只要忽略它們。 –
,因爲我需要追加相同的列和值從另一個動態樞軸值 – user1882705
所以,爲什麼你不等待構建#temp表,直到你知道所有的列將是什麼?或者只是命名新列first_name2,last_name2等?或者首先避免#temp表?你知道你將有一段時間鞏固範圍,試圖構建和更改#temp表,同時還需要使用動態SQL ... –