TSQL Параметризованный вопрос SPROC - PullRequest
1 голос
/ 06 мая 2009

Мне нужно написать хранимую процедуру для обновления одного из набора похожих столбцов. Столбцы называются «UserField1», «UserField2» и т. Д. Я надеялся передать параметр в SPROC, который установит столбец для обновления. Тем не менее, я не могу получить правильный код. Вот упрощенный пример того, что я пробовал (что дает мне сообщение «Неверный синтаксис»):

create procedure UpdateUserField
    (@UserFieldNumber int, @UserFieldNewValue int)
as
    update MyTable set
        case @UserFieldNumber
        when 1 then UserField1
        when 2 then UserField2
        end
    = @UserFieldNewValue

Ответы [ 6 ]

2 голосов
/ 06 мая 2009

Если вы не хотите использовать динамический SQL или несколько операторов IF и UPDATE, вы можете попробовать что-то вроде этого:

UPDATE MyTable
SET UserField1 = CASE WHEN @UserFieldNumber = 1
        THEN @UserFieldNewValue ELSE UserField1 END,
    UserField2 = CASE WHEN @UserFieldNumber = 2
        THEN @UserFieldNewValue ELSE UserField2 END
2 голосов
/ 06 мая 2009

Как насчет использования нескольких ПЧ?

CREATE PROCEDURE UpdateUserField
(
    @UserFieldNumber int,
    @UserFieldNewValue int
) AS

IF @UserFieldNumber=1
BEGIN
    UPDATE MyTable SET UserField1 = @UserFieldNewValue
END

IF @UserFieldNumber=2
BEGIN
    UPDATE MyTable SET UserField2 = @UserFieldNewValue
END

В качестве альтернативы вы можете построить динамический SQL в exec

CREATE PROCEDURE UpdateUserField
(
    @UserFieldNumber int,
    @UserFieldNewValue int
) AS

EXEC('UPDATE MyTable SET UserField' + CONVERT(varchar(10), @UserFieldNumber) + ' = ' + CONVERT(varchar(10), @UserFieldNewValue))

Остерегайтесь SQL-инъекций, если вы делаете это, хотя с целыми числами у вас не возникнет проблем, все остальное вам может понадобиться, чтобы учитывать риски.

0 голосов
/ 06 мая 2009

AFAIK, вы не можете использовать CASE WHEN, чтобы указать столбец.

Вы могли бы обернуть это в Некоторый Динамический SQL все же.

CREATE PROCEDURE UpdateUserField
( 
    @UserFieldNumber int, 
    @UserFieldNewValue int
)
AS

DECLARE @sql nvarchar(max)
SET @sql = 'UPDATE MyTable SET UserField' + @UserFieldNumber + ' = ' + @UserFieldNewValue
EXEC (@sql)
0 голосов
/ 06 мая 2009

Команда обновления не принимает динамические имена полей.

Вместо этого вы можете создать строку с оператором обновления, который вы хотите выполнить, а затем выполнить его следующим образом:

DECLARE @strToExecute VARCHAR(1000)
SET @strToExecute = 'UPDATE MyTable '
IF @UserFieldNumber = 1 
  SET @strToExecute = @strToExecute + ' SET UserField1 = '
IF @UserFieldNumber = 2
  SET @strToExecute = @strToExecute + ' SET UserField2 = '

И так далее, чтобы построить вашу строку, а затем выполнить ее.

0 голосов
/ 06 мая 2009
if @UserFieldNumber=1
BEGIN
    update MyTable set UserField1=@UserFieldNewValue where...
END
ELSE if @UserFieldNumber=2
BEGIN
    update MyTable set UserField2=@UserFieldNewValue where...
END
ELSE if @UserFieldNumber=3
BEGIN
    update MyTable set UserField3=@UserFieldNewValue where...
END
0 голосов
/ 06 мая 2009

Я не думаю, что вы можете использовать операторы CASE в списках полей в операторах. Я почти уверен, что вы можете применять операторы CASE только к значениям, которые вы устанавливаете, возвращаете или тестируете.

В вашем примере вы пытаетесь изменить список полей, используя операторы case, и я предполагаю, что у SQL есть проблемы с ним, потому что список полей не будет определен до тех пор, пока оператор не будет скомпилирован и запущен, что является своего рода ситуация с курицей и яйцом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...