2012-06-06 115 views
1

我想創建一個動態查詢,根據錯誤代碼選擇一個特定的列。動態添加列查詢

,比如我有一個錯誤表(ErrorTable),其中包含多個列:

Transaction Number 
Transaction Amount 
Transaction Date 
Error Code 
Error Description 
+100 other columns 

錯誤表

Error Code 
Error Description 
Error Column 

我想獲得一個查詢,會得到如下:

ErrorCode 
ErrorDescription 
ErrorColumn (Column Based On Error Code) 

我嘗試使用如下的動態SQL,仍然只有c的名稱olumn回來了,也許我做錯了什麼?

DECLARE @SQL VarChar(1000) 
SELECT @SQL = 'SELECT et.ErrorCode, et.ErrorDescription, e.ErrorColumn 
       FROM ErrorTable et 
        INNER JOIN Errors e ON e.ErrorCodeID = et.ErrorCode' 
Exec (@SQL) 

如果我使用@ErrorColumn =代替e.ErrorColumn「TransactionDate」的動態查詢我得到的結果,但與上面的查詢我不知道。有任何想法嗎?

更新2

我得到上面的查詢結果如下:

ErrorCode ErrorDesc    TransactionDate TransactionAmount 
1   Invalid Trans Date  TransactionDate TransactionAmount 
2   Invalid Trans Amount TransactionDate TransactionAmount 

我想以下幾點:

ErrorCode ErrorDesc    TransactionDate TransactionAmount 
1   Invalid Trans Date  May 1st    
2   Invalid Trans Amount      65 Cats 
+0

您的示例select語句無效。您選擇沒有別名錶前綴的ErrorCode。哪個表是從哪裏來的? – VenerableAgents

+0

如果我正在閱讀此權限,那麼您的列名稱存儲在Errors.ErrorColumn中,並且您希望錯誤類型確定選擇了哪一列。如果錯誤類型的數量不是很大,請考慮編寫一個CASE語句。否則,你將不得不使用動態SQL。 – SQLCurious

+0

它給你什麼錯誤? – ganders

回答

1

你的意思要做到這一點:

DECLARE @ErrorColumn SYSNAME = N'TransactionDate'; 
-- presumably the above is a parameter to the procedure 

DECLARE @sql NVARCHAR(MAX); 

SELECT @sql = N'SELECT et.ErrorCode, et.ErrorDescription, et.' 
    + QUOTENAME(@ErrorColumn) 
    + ' FROM dbo.ErrorTable AS et 
     INNER JOIN dbo.Errors AS e 
     ON e.ErrorCodeID = et.ErrorCode;'; 

EXEC sp_executesql @sql; 

基礎上,進一步的信息,也許你想要的是這樣的:

SELECT et.ErrorCode, et.ErrorDescription, 
    TransactionDate = CASE et.ErrorColumn WHEN N'TransactionDate' 
    THEN e.TransactionDate ELSE NULL END, 
    TransactionAmount = CASE et.ErrorColumn WHEN N'TransactionAmount' 
    THEN e.TransactionAmount ELSE NULL END 
FROM dbo.ErrorTable AS et 
INNER JOIN dbo.Errors AS e 
ON et.ErrorCode = e.ErrorCodeID; 

或者這樣:

SELECT et.ErrorCode, et.ErrorDescription, 
    TransactionDate = CASE et.ErrorColumn WHEN N'TransactionDate' 
    THEN e.TransactionDate ELSE '' END, 
    TransactionAmount = CASE et.ErrorColumn WHEN N'TransactionAmount' 
    THEN e.TransactionAmount ELSE '' END 
FROM dbo.ErrorTable AS et 
INNER JOIN dbo.Errors AS e 
ON et.ErrorCode = e.ErrorCodeID; 

如果需要只返回實際存在的數據集列,它是略更令人費解。您基本上必須構建動態SQL以僅包含最終查詢中必須引用的列。

DECLARE @sql NVARCHAR(MAX) = N''; 

SELECT @sql += ',' + CHAR(13) + CHAR(10) 
    + et.ErrorColumn + ' = CASE et.ErrorColumn WHEN N''' 
    + et.ErrorColumn + ''' THEN e.' + et.ErrorColumn + ' ELSE NULL END' 
FROM dbo.ErrorTable AS et INNER JOIN dbo.Errors AS e 
ON et.ErrorCode = e.ErrorCodeID 
GROUP BY et.ErrorColumn; 

SELECT @sql = N'SELECT et.ErrorCode, et.ErrorDescription' 
    + @sql + ' 
    FROM dbo.ErrorTable AS et 
INNER JOIN dbo.Errors AS e 
ON et.ErrorCode = e.ErrorCodeID;'; 

PRINT @sql; 

-- EXEC sp_executesql @sql; 
+0

這可以正常工作,但我不想傳入參數。有沒有辦法做到這一點,而不傳入參數,只使用Errors表中的值?這就是我的意思,我得到它來工作@ErrorColumn,我的意思是,如果你傳入一個參數,它按預期工作(即返回表值)。謝謝! – buzzzzjay

+0

好的,請展示一些樣本數據和期望的結果 - 我們根本不會根據您現在的問題猜出這些。你想要一個特定的行或所有行的結果嗎?例如。如果一個錯誤表示TransactionDate,另一個表示TransactionNumber,那麼您希望同一列顯示一行1月5日,另一行顯示12345? –

+0

更新了OP的細節。對不起,我的問題不清楚。我考慮的越多,使用參數並單獨運行每個錯誤代碼可能會更好。謝謝。 – buzzzzjay