簡體   English   中英

嘗試使用c#執行查詢時SqlCommand返回錯誤

[英]SqlCommand is returning an error when attempting to execute a query using c#

我正在開發一個項目,允許用戶只通過選擇列來構建查詢。

我的應用程序似乎工作正常並生成正確的查詢。 但是當我執行查詢時,我得到以下異常

列'Tasks.Duration'在選擇列表中無效,因為它不包含在聚合函數或GROUP BY子句中。

這里沒有做的是我的查詢實際上包含了正確的GROUP BY語句

這是我的應用程序生成的查詢

SELECT
 [Campaign].[Title] AS [CampaignTitle]
,CASE WHEN [Task].[Duration] <= @p0 THEN @p1 WHEN [Task].[Duration] >= @p2 AND [Task].[Duration] <= @p3 THEN @p4 ELSE @p5 END AS [9pl1WbY1ZkSvSpel3g4xmw]
,COUNT(1) AS [Ib7ZS4arHkSUWhf4saEtmg]
,SUM(CASE WHEN [Task].[Duration] <= @p6 THEN @p7 ELSE @p8 END) AS [xW1GmttC6kWHsc9QIEPN9w]
FROM [Tasks] AS [Task]
INNER JOIN [Campaigns] AS [Campaign] ON [Campaign].[Id] = [Task].[CampaignId]
INNER JOIN [Users] AS [User] ON [User].[Id] = [Task].[CompletedBy]
INNER JOIN [Results] AS [Result] ON [Result].[Id] = [Task].[ResultId]
WHERE
[Result].[IsCompleted] = @p9 AND ( [User].[LastName] = @p10 OR [User].[LastName] = @p11 )
GROUP BY
[Campaign].[Title]
,CASE WHEN [Task].[Duration] <= @p13 THEN @p14 WHEN [Task].[Duration] >= @p15 AND [Task].[Duration] <= @p16 THEN @p17 ELSE @p18 END
HAVING
COUNT(1) >= @p12
ORDER BY
 [Campaign].[Title]
,CASE WHEN [Task].[Duration] <= @p19 THEN @p20 WHEN [Task].[Duration] >= @p21 AND [Task].[Duration] <= @p22 THEN @p23 ELSE @p24 END

更好的是,我嘗試用參數值手動替換參數名稱。 然后我把它們輸出查詢,我在SSMS中執行它,它沒有任何問題。

這就是我執行查詢的方式

using (SqlConnection connection = new SqlConnection(this.connectionString))
using (SqlDataAdapter sqlAdapter = new SqlDataAdapter(selectCommand))
{
    try
    {
        selectCommand.Connection = connection;

        DataTable table = new DataTable();

        sqlAdapter.Fill(table);

        return table;
    }
    catch (Exception e)
    {
        throw new ReportException(string.Format("{0} {1}", e.Message, e.GetType().FullName));
    }
}

這是我用來用它們的值替換參數的方法

private string GetPlainQuery(SqlCommand selectCommand)
{
    string output = selectCommand.CommandText;

    for (int i = selectCommand.Parameters.Count - 1; i >= 0; i--)
    {
        var p = selectCommand.Parameters[i];

        string value = p.Value.ToString();

        if (p.SqlDbType == SqlDbType.NChar || p.SqlDbType == SqlDbType.NText || p.SqlDbType == SqlDbType.NVarChar || p.SqlDbType == SqlDbType.Text || p.SqlDbType == SqlDbType.Char || p.SqlDbType == SqlDbType.Date || p.SqlDbType == SqlDbType.DateTime || p.SqlDbType == SqlDbType.SmallDateTime)
        {
            value = string.Format("'{0}'", value.Replace("'", "''"));
        }

        output = output.Replace(p.ParameterName, value);
    }

    return output;
}

導致此錯誤的原因是什么? 我該如何解決?

更新

這是我用值替換參數后的查詢

SELECT
 [Campaign].[Title] AS [CampaignTitle]
,CASE WHEN [Task].[Duration] <= 100 THEN '<100' WHEN [Task].[Duration] >= 100 AND [Task].[Duration] <= 200 THEN 'BETWEEN 100 AND 200' ELSE '>200' END AS [9pl1WbY1ZkSvSpel3g4xmw]
,COUNT(1) AS [Ib7ZS4arHkSUWhf4saEtmg]
,SUM(CASE WHEN [Task].[Duration] <= 100 THEN 1 ELSE 0 END) AS [xW1GmttC6kWHsc9QIEPN9w]
FROM [Tasks] AS [Task]
INNER JOIN [Campaigns] AS [Campaign] ON [Campaign].[Id] = [Task].[CampaignId]
INNER JOIN [Users] AS [User] ON [User].[Id] = [Task].[CompletedBy]
INNER JOIN [Results] AS [Result] ON [Result].[Id] = [Task].[ResultId]
WHERE
[Result].[IsCompleted] = 1 AND ( [User].[LastName] = 'Yo' OR [User].[LastName] = 'Smith' )
GROUP BY
 [Campaign].[Title]
,CASE WHEN [Task].[Duration] <= 100 THEN '<100' WHEN [Task].[Duration] >= 100 AND [Task].[Duration] <= 200 THEN 'BETWEEN 100 AND 200' ELSE '>200' END
HAVING
COUNT(1) >= 0
ORDER BY
 [Campaign].[Title]
,CASE WHEN [Task].[Duration] <= 100 THEN '<100' WHEN [Task].[Duration] >= 100 AND [Task].[Duration] <= 200 THEN 'BETWEEN 100 AND 200' ELSE '>200' END

我的猜測是錯誤是由於你在選擇列表中的case語句與你的組中的case語句不同。 我通常做的是在子查詢中解析這些列,以便更容易閱讀和維護外部查詢。

我在這里缺少的是框架將在替換參數之前首先驗證它們的查詢。

由於參數名稱在select和group by中不同,因此框架假設它們具有導致問題的不同值。

解決方案是重用相同的參數名稱,以使框架保證值相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM