2016-12-02 71 views
0

我想在动态SQL语句中使用变量作为列名的一部分。使用变量作为动态SQL中列名的一部分

我有4列,称为Player1Action,Player2Action,Player3ActionPlayer4Action

取决于变量@CurrentPlayerId,我想用一些数据更新相关玩家列。

因此,例如,如果CurrentPlayerId包含1,则更新列Player1Action

我意识到我可以通过一系列的IF语句来实现这一点,但我希望以更清晰的方式来实现。

我有以下代码,但我认为我的转义导致了问题。我已经重新编写了这个视图时间,但我似乎无法使其工作。

DECLARE 
@CurrentPlayerId INT, 
@CurrentPlayerBetAmount nvarchar(MAX), 
@stmt nvarchar(MAX); 

SET @CurrentPlayerId = 1 
SET @CurrentPlayerBetAmount = 100 

SET @stmt = N'UPDATE HandCurrent SET ''Player'' ''+'' @CurrentPlayerId ''+'' ''Action'' = 1 '','' ''Player'' ''+'' @CurrentPlayerId ''+'' ''ActionSize'' = @CurrentPlayerBetAmount' 

EXECUTE sp_executesql @stmt 

如果我将它作为select运行,则返回以下结果。

UPDATE HandCurrent SET 'Player' '+' @CurrentPlayerId '+' 'Action' = 1 ',' 'Player' '+' @CurrentPlayerId '+' 'ActionSize' = @CurrentPlayerBetAmount 
+0

请RDBMS疑问句你使用 – Kacper

+0

为什么不用'SELECT @ stmt'来查看结果sql? –

+0

@ Kacper完成了,谢谢! – AntonZ

回答

2
DECLARE 
@CurrentPlayerId INT, 
@CurrentPlayerBetAmount INT, 
@stmt nvarchar(MAX); 

SET @CurrentPlayerId = 1 
SET @CurrentPlayerBetAmount = 100 

SET @stmt = N'UPDATE HandCurrent SET 
      Player' + CAST(@CurrentPlayerId AS NVARCHAR(10)) + 'Action = 1, 
      Player' + CAST(@CurrentPlayerId AS NVARCHAR(10)) + 'ActionSize = ' 
      + CAST(@CurrentPlayerBetAmount AS NVARCHAR(10)) 

EXECUTE sp_executesql @stmt 

胡安·卡洛斯说得对唯一的问题是变量@CurrentPlayerId数据类型是INT,所以你需要将它转换为NVARCHAR()https://www.mssqltips.com/sqlservertip/3014/concatenation-of-different-sql-server-data-types/

为了保持一致性,您应该已将@CurrentPlayerBetAmount标为INT。如果你这样做,那么你也需要投它。

DECLARE 
@CurrentPlayerId NVARCHAR(MAX), 
@CurrentPlayerBetAmount NVARCHAR(MAX), 
@stmt nvarchar(MAX); 

SET @CurrentPlayerId = '1' 
SET @CurrentPlayerBetAmount = '100' 

SET @stmt = N'UPDATE HandCurrent SET 
      Player' + @CurrentPlayerId + 'Action = 1, 
      Player' + @CurrentPlayerId + 'ActionSize = ' + @CurrentPlayerBetAmount 

EXECUTE sp_executesql @stmt 

还是我的偏好,如果你打算无论如何要更改记录将只是做:

但是,你也可以简单地设置它,当如同时声明为NVARCAHR(MAX),然后单引号的价值更新声明,如果你有4列。你也可以认为第n正常化,使列排....

DECLARE @CurrentPlayerId INT = 1 
DECLARE @CurrentPlayerBetAmount INT = 100 

UPDATE HandCurrent 
    Player1Action = CASE WHEN @CurrentPlayerId = 1 THEN 1 ELSE PlayerAction1 END 
    ,Player1ActionSize = CASE WHEN @CurrentPlayerId = 1 THEN @CurrentPlayerBetAmount ELSE Player1ActionSize END 
    ,Player2Action = CASE WHEN @CurrentPlayerId = 2 THEN 1 ELSE PlayerAction2 END 
    ,Player2ActionSize = CASE WHEN @CurrentPlayerId = 2 THEN @CurrentPlayerBetAmount ELSE Player2ActionSize END 
    ,Player3Action = CASE WHEN @CurrentPlayerId = 3 THEN 1 ELSE PlayerAction3 END 
    ,Player3ActionSize = CASE WHEN @CurrentPlayerId = 3 THEN @CurrentPlayerBetAmount ELSE Player3ActionSize END 
    ,Player4Action = CASE WHEN @CurrentPlayerId = 4 THEN 1 ELSE PlayerAction4 END 
    ,Player4ActionSize = CASE WHEN @CurrentPlayerId = 4 THEN @CurrentPlayerBetAmount ELSE Player4ActionSize END 
WHERE 
    ???? 

注意你实际上是更新整个表,你的愿望是什么?

+0

这是完美的!谢谢 – AntonZ

2

不要引用变量。

SET @stmt = N'UPDATE HandCurrent SET 
      Player' + @CurrentPlayerId + 'Action = 1, 
      Player' + @CurrentPlayerId + 'ActionSize = ' + @CurrentPlayerBetAmount 
+1

不要引用操作员。 OP有他们双重单引号。 –

+0

感谢您的建议,这不适合我,因为它似乎表明缺少一个qoute。 – AntonZ

+0

你能告诉我stmt的结果吗? –

0

说到干净的方式做到这一点,恕我直言,最好的方法是使用sp_executesql与参数,这意味着给定的代码的@CurrentPlayerId@CurrentPlayerBetAmount输入参数:

Declare @sql nvarchar(256) 
    , @sql1 nvarchar(256) = N'update HandCurrent 
    Set Player1Action [email protected], 
    Player1ActionSize [email protected]' 
    , @sql2 nvarchar(256) = N'update HandCurrent 
    Set Player2Action [email protected], 
    Player2ActionSize [email protected]' 
    , @params nvarchar (128) 
    , @CurrentPlayerId int 
    ; 

Select @sql = case @CurrentPlayerId when 1 then @sql1 when 2 then @sql2 else '' end; 
If @sql <> '' begin 
    set @params = N'@value int, @size int'; 
    execute sp_executesql @sql, @params, 
     @value =1, 
     @size = @CurrentPlayerBetAmount 
     ; 
End 
+0

虽然我同意动词sql,但你可以解决的问题是,该参数被用来动态识别要更新的列名。所以这对于这种情况不起作用,但它可以用于BetAmount,因为在这个特殊情况下可以参数化为 – Matt

+0

是,但是如果@ CurrentPlayerId是输入参数,那么可以有更多的逻辑依赖于它的UDF。在这种情况下,我们可以将值赋给'@ sql'并执行其他操作 –

相关问题