C#

2016-07-28 2 views
1

을 사용하여 쿼리를 실행하려고하면 SqlCommand가 오류를 반환합니다. 사용자가 열을 선택하기 만하면 쿼리를 작성할 수있는 프로젝트를 진행하고 있습니다.C#

내 응용 프로그램이 제대로 작동하고 올바른 쿼리를 생성하는 것 같습니다. 내가 쿼리를 실행할 때 나는 집계 함수 나 GROUP BY 절 중 하나에 포함되지 않기 때문에 선택 목록에서 유효하지 않은 다음과 같은 예외를

열 '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; 
} 

으로 매개 변수를 대체하기 위해 사용되는 방법은 실행 방법

이 무엇입니까? 어떻게 해결할 수 있습니까?

나는 값으로 매개 변수를 대체 한 후 여기에

쿼리가입니다

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 테이블 '작업'이 '작업'으로 앨리어스 (alias)되고 있기 때문입니다. – juharr

답변

3

내 생각 엔 오류가 같은 선택 목록에서 case 문에 의한되지 않은 점이다 귀하의 그룹에 속한 그룹입니다. 일반적으로 수행하는 작업은 외부 쿼리를 읽고 유지하는 것이 더 쉽도록 하위 쿼리에서 이러한 열을 해결하는 것입니다.

+0

내 쿼리를 보면 선택한 열과 그룹 by의 유일한 차이점이 매개 변수 이름이지만 값은 동일합니다. 이것이 문제가 될 수 있습니까? –

+1

@MikeA 다른 매개 변수를 사용하는 이유는 무엇입니까? 쿼리에서 매개 변수를 두 번 이상 사용할 수 있다는 것을 알지 못합니까? – juharr

+0

@juharr 예 저는 같은 매개 변수를 다시 사용할 수 있다는 것을 모릅니다! 그 메모를 가져 주셔서 감사합니다. 하지만이 오류가 발생할 수 있습니까? –

0

여기서 누락 된 것은 프레임 워크가 매개 변수를 대체하기 전에 먼저 쿼리의 유효성을 검사한다는 것입니다.

매개 변수 이름이 select 및 group by 다른 경우 프레임 워크는 서로 다른 값을 갖고있어 문제를 일으킨다 고 가정합니다.

해결책은 동일한 매개 변수 이름을 다시 사용하여 값이 동일하다는 프레임 워크 보증을 제공하는 것이 었습니다.