动态添加列以进行查询

时间:2012-06-06 18:21:07

标签: sql sql-server-2008 tsql dynamic

我正在尝试创建一个动态查询,根据错误代码选择特定列。

例如,我有一个包含多列的错误表(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,如下所示,仍然只返回列的名称,也许我做错了什么?

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 =' TransactionDate'而不是动态查询中的e.ErrorColumn我得到了结果,但是上面的查询我不知道。有任何想法吗?

更新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

1 个答案:

答案 0 :(得分: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;