2009-05-06 62 views
1

我需要编写一个存储过程来更新一组相似列中的一个。这些列被命名为“UserField1”,“UserField2”等。我希望将参数传递给SPROC,它将设置要更新的列。但是,我似乎无法得到正确的代码。下面是我的尝试(这让我的“语法错误”消息)一个简单的例子:TSQL参数化SPROC问题

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

地方它说了“不正确的语法”在发生脚本? '关键字'CASE'附近的' – 2009-05-06 15:18:48

+0

'。 – dsteele 2009-05-06 15:25:14

回答

2

如何使用多个IF?

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注入,如果你做到这一点虽然与整数你会不会有问题,其他任何你可能需要考虑风险。

-1

我不认为你可以在语句中使用CASE语句中字段列出。我几乎肯定你只能将CASE陈述应用于你正在设置,返回或测试的值。

在你的例子中,你试图用case语句来修改字段列表,并且我假设SQL有问题,因为直到语句被编译并运行之后,字段列表才会被确定,这是一种鸡和鸡蛋的情况。

0
if @UserFieldNumber=1 
BEGIN 
    update MyTable set [email protected] where... 
END 
ELSE if @UserFieldNumber=2 
BEGIN 
    update MyTable set [email protected] where... 
END 
ELSE if @UserFieldNumber=3 
BEGIN 
    update MyTable set [email protected] where... 
END 
+0

这是一个可怕的可怕的解决方案:( 如果他有50个可能的领域... 该sproc将是巨大的 – 2009-05-06 15:25:11

+0

@Eoin坎贝尔,他已经有一个可怕的设计,但不能超过语法错误,他有很多问题,最少的是这个解决方案! – 2009-05-06 15:30:07

+0

Gee,谢谢:)这里的背景是我必须从内部程序更新MS Outlook的Microsoft Business Contact Manager插件中的表格。 – dsteele 2009-05-06 15:32:30

0

update命令不接受动态字段名称。

相反,你可以做的是建立与您要执行更新语句的字符串,然后执行它,就像这样:

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

第4行和第6行的第二个'='应该是'+' – 2009-05-06 15:49:26

+0

哈!你是对的。修正了 - 很好的结果。当我在那里的时候,把它变成一个社区维基,以便其他人可以修复更多的错别字,哈哈哈。 – 2009-05-06 15:57:18

-1

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

您的代码将导致错误,您不能将int连接到一个字符串上,并且空值将会填充整个字符串 – 2009-05-06 15:32:12

2

如果你不想使用动态SQL或多个IFUPDATE语句的话,你可以尝试这样的东西,而不是:

UPDATE MyTable 
SET UserField1 = CASE WHEN @UserFieldNumber = 1 
     THEN @UserFieldNewValue ELSE UserField1 END, 
    UserField2 = CASE WHEN @UserFieldNumber = 2 
     THEN @UserFieldNewValue ELSE UserField2 END