2015-01-08 4 views
2
DECLARE @sql NVARCHAR(max) 
DECLARE @ParmDefinition NVARCHAR(500) 
SET @sql = 'UPDATE [Table1] SET [Table1].[@columnName] = TEST'; 
SET @ParmDefinition = N'@columnName NVARCHAR(50)'; 
EXEC sp_executesql @sql, @ParmDefinition, @columnName = N'MyColumn'; 

Когда я запускаю вышеуказанный запрос, я получаю Invalid column name '@columnName'.. Очевидно, что имя столбца не заменяется при выполнении запроса.Динамическое имя столбца в SQL в заявлении об обновлении

В действительности, моя переменная @sql намного больше, и у меня есть много столбцов, которые я хочу обновить, поэтому я бы хотел избежать SET SQL = для всех перечислений имени столбца.

Я хотел бы объявить строку sql один раз и вызвать запрос с разными значениями. например:

EXEC sp_executesql @sql, @ParmDefinition, @columnName = N'MyColumn'; 
EXEC sp_executesql @sql, @ParmDefinition, @columnName = N'AnotherColumn'; 
EXEC sp_executesql @sql, @ParmDefinition, @columnName = N'YetAnotherColumn'; 
-- And so on 

Возможно ли это как можно?

ответ

4

Да, вы должны конкатенировать переменную за пределами строки. Другими словами:

SET @sql = 'UPDATE [Table1] SET [Table1].[' + @columnName + '] = t1.Value ' + 

EDIT: Еще одно решение, мы использовали, чтобы заменить маркеры в базовой SQL, чтобы построить новую переменную SQL для выполнения.

DECLARE @sql nvarchar(max) = 'SELECT @ColumnName FROM @TableName'; 

DECLARE @sql2 nvarchar(max) = REPLACE(REPLACE(@sql,'@ColumnName',@ColumnNameVariable),'@TableName',@TableNameVariable) 

EXEC (@sql2) 

...Some code that changes the values of @ColumnNameVariable and @TableNameVariable... 

DECLARE @sql2 nvarchar(max) = REPLACE(REPLACE(@sql,'@ColumnName',@ColumnNameVariable),'@TableName',@TableNameVariable) 

EXEC (@sql2) 

И вы заметите, что декларация и Exec SQL2 являются точно такими же строками в обоих случаях. Это позволяет использовать в LOOP, если это применимо. (За исключением того, что вы не должны DECLARE @ Sql2 в цикле ... просто заполнить/повторно заполнить его).

+0

Я хочу, чтобы иметь возможность запускать '' sp_executesql и кормить '@ columnName' с разными значениями, хотя. –

+0

В действительности моя переменная @sql намного больше. Я хотел бы объявить строку sql один раз и вызвать запрос с разными значениями. –

+0

Хорошо, я понимаю, что вы имеете в виду. Вы можете попробовать решение Xedni, или я отредактирую свой ответ другим решением, которое мы использовали в прошлом. –

3

Прежде всего, надобно попытаться параметризовать ваш dsql, используя sp_executesql. Проблема в том, что вы можете параметризовать только то, что вы могли бы поместить в переменную, в первую очередь, например, в предикат поиска или список выбора.

Однако это все еще возможно; просто сцепить имя столбца с DSQL строки, окружив его с функцией quotename

set @sql = 'update table1 set table1.' + quotename(@ColumnName) + ' = ... 
+0

Если у меня есть (я) несколько столбцов, мне придется «SET @sql = ...» для каждого столбца, да? –

+0

Да, условно. Я не знаю точно, что вы пытаетесь выполнить, но теоретически вы можете построить одну строку, содержащую все столбцы, которые вы хотите обновить, и запустить ее сразу. Кроме того, если вы обновляете одно значение в строке или каждом столбце в строке, SQL должен выполнять столько же работы. Если столбцы из них неизвестны во время выполнения обновления, вы, вероятно, можете сделать это со статически типизированным SQL и isnulls таблица обновленийset Column1 = isnull (@ column1, Column1) Column2, isnull (@ column2, isnull (@ column2, Столбец2) – Xedni