Я согласен с лукавыми 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 ... –