2016-12-02 38 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'並執行其他操作 –

相關問題