2012-06-06 99 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