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,但仍然只返回了列的名称,也许我做错了什么?

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
4

1 回答 1

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;
于 2012-06-06T18:47:27.933 回答