2016-07-28 6 views
1

私は、ユーザーが列を選択するだけでクエリを構築できるようにするプロジェクトを進めています。C#を使用してクエリを実行しようとするとSqlCommandがエラーを返す

私のアプリケーションはうまく動作しており、正しいクエリが生成されているようです。それは BY句集計関数またはGROUPのいずれかに含まれていないので、しかし、私は、クエリを実行すると、私は次の例外を取得し

列「Tasks.Durationは、」選択リストでは無効です。ここで以来、ことはありません何

は私が手動で交換してみました、私のクエリは実際にここで正しい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; 
} 

でパラメータを置き換えるために使用される方法はありますか?どうすれば修正できますか?

ここで私は私の推測では、エラーが選択リストであなたのcase文によるものであることは同じではないということです値

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 
+1

エラーは 'Tasks.Duration'と表示されますが、SQLクエリでは' Task.Duration'しか表示されません。見落としているタイプミスはありますか? –

+0

パラメータを使用せずに、通常のクエリを教えてもらえますか? – Surendra

+0

@JonathonOgden私はこれは、 'Tasks'テーブルが' Task'としてエイリアス化されているからです。 – juharr

答えて

3

でパラメータを交換した後、クエリがあるを更新しましたあなたのグループのメンバーとして。私が通常行っているのは、サブクエリ内のこれらの列を解決して、外側のクエリを読みやすく、維持することです。

+0

私のクエリを見ると、選択した列とグループの唯一の違いはパラメータ名ですが値は同じです。これは問題なのでしょうか? –

+1

@MikeAなぜ異なるパラメータを使用するのですか?クエリでパラメータを複数回使用できることに気付かないのですか? – juharr

+0

@juharrはい私は同じパラメータを再利用できることに気づいていません!そのメモをありがとう。しかし、それはこのエラーを引き起こす可能性がありますか? –

0

私がここで欠落していたことは、フレームワークが最初にパラメータを置き換える前にクエリを検証することです。

selectとgroupでパラメータ名が異なるため、フレームワークは異なる値を持っているとみなして問題を引き起こします。

解決策は、同じパラメータ名を再利用して値が同じであることをフレームワークに保証することでした。

関連する問題