Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TSQL参数化存储过程问题_Sql_Sql Server_Sql Server 2005_Tsql - Fatal编程技术网

TSQL参数化存储过程问题

TSQL参数化存储过程问题,sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,我需要编写一个存储过程来更新一组类似列中的一列。这些列名为“UserField1”、“UserField2”等等。我希望向存储过程传递一个参数,该参数将设置要更新的列。然而,我似乎无法获得正确的代码。下面是我尝试的一个简化示例(这会给我一条“语法错误”的消息): 我认为您不能使用CASE语句来定义语句中的字段列表。我几乎可以肯定,您只能对正在设置、返回或测试的值应用CASE语句 在您的示例中,您试图使用case语句修改字段列表,我假设SQL有问题,因为字段列表在语句编译和运行之后才能确定,这是一

我需要编写一个存储过程来更新一组类似列中的一列。这些列名为“UserField1”、“UserField2”等等。我希望向存储过程传递一个参数,该参数将设置要更新的列。然而,我似乎无法获得正确的代码。下面是我尝试的一个简化示例(这会给我一条“语法错误”的消息):


我认为您不能使用CASE语句来定义语句中的字段列表。我几乎可以肯定,您只能对正在设置、返回或测试的值应用CASE语句


在您的示例中,您试图使用case语句修改字段列表,我假设SQL有问题,因为字段列表在语句编译和运行之后才能确定,这是一种鸡和蛋的情况。

使用一些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
或者,您可以在exec中构建动态SQL

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

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

谨防SQL注入,如果您这样做,用Its将不会有问题,任何其他可能需要考虑的风险。

< P>更新命令不接受动态字段名称。

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
相反,您可以使用要执行的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 = '

依此类推,以构建字符串,然后执行它。

好吧,指定列时不能使用大小写

不过,您可以将其封装在一些动态SQL中

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

DECLARE @sql nvarchar(max)
SET @sql = 'UPDATE MyTable SET UserField' + @UserFieldNumber + ' = ' + @UserFieldNewValue
EXEC (@sql)

如果您不想使用动态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

脚本中哪里出现了“不正确的语法?”这是一个可怕的解决方案:(如果他有50个可能的字段……存储过程将是huge@Eoin坎贝尔,他已经有了一个可怕的设计,但无法克服语法错误,他有很多问题,至少是这个解决方案!哎呀,谢谢:)这里的背景是,我必须从内部程序更新Microsoft Business Contact Manager附加模块中MS Outlook的一个表。通常,列:UserField1、UserField2、UserField3等都应该是新表中的行。如果有50个,它们应该是行,如果有2个,比如address1,address2,那么列……您的代码将导致一个错误,您不能将int连接到字符串上,null将清空整个字符串。第4行和第6行的第二个“=”应该是“+”Ha!你说得太对了。修正了这个问题-很好的捕捉。我在那里的时候把它变成了一个社区维基,这样其他人可以修正更多的拼写错误,哈哈哈。
UPDATE MyTable
SET UserField1 = CASE WHEN @UserFieldNumber = 1
        THEN @UserFieldNewValue ELSE UserField1 END,
    UserField2 = CASE WHEN @UserFieldNumber = 2
        THEN @UserFieldNewValue ELSE UserField2 END