2010-06-02 4 views
0

데이터베이스에있는 이름의 하위 집합을 보유하고있는 arraylist가 있습니다. 특정 섹션에 대한 arraylist에있는 사람들의 수를 얻기 위해 쿼리를 작성해야합니다. 이름이 arraylist 인 사람들이 내 데이터베이스에 "City"필드가 있습니다. 얼마나 많은 사람들이 시카고에 살고 있는지 알고 싶습니다. , 뉴욕에 얼마나 많은 사람이 살고 있습니까?데이터의 하위 집합을 필터링하는 SQL

이 문제를 처리하기 위해 SQL 문을 어떻게 설정할 수 있습니까? 어떻게 든 나는 SQL에 이름의 하위 집합을 어떻게 든 전달해야한다고 생각합니다.

가 여기 내 코드에 내 SQL을 쓰고 어떻게 샘플입니다

Public Shared Function GetCAData(ByVal employeeName As String) As DataTable 
     Dim strQuery As String = "SELECT EMPLID, EMPLNME, DISP_TYPE, BEGIN_DTE FROM Corr WHERE (EMPLNME = @name)" 
     Dim cmd As New SqlCommand(strQuery) 
     cmd.Parameters.Add("@name", SqlDbType.VarChar) 
     cmd.Parameters("@name").Value = employeeName 
     Dim dt As DataTable = GenericDataAccess.GetData(cmd) 
     Return dt 
End Function 

나는 이름의 DataTable 개체를 반환하는 SQL 문을 사용하여 함수를 만드는 방법이 필요하고 매개 변수가 도시가 될 것입니다, 및 이름 목록.

위의 예에서는 SQL을 사용하지 않고 작성하고자하는 함수의 뼈대를 찾고 있습니다.

그렇다면 fron 끝에서 매번 동일한 이름 집합을 전달하는 모든 도시를 반복하여 함수를 사용할 수 있습니다.

select city, count(*) 
from table 
where city in ('Chicago', 'New York') 
group by city 

도시의 목록이 ArrayList에 있습니다 :

+0

나는 또한 .Net 2.0을 사용하고 있으므로 새로운 것들은 잘 작동하지 않을 것이다. –

답변

0

최상의 접근 방식은 이름의 하위 집합이 얼마나 큰지에 달려 있습니다.

매우 간단하고, 아마 최악의 접근 방식은이 같은 일부 동적 SQL을 생성하는 것입니다 .. 아마 다음

private string CreateSQL(List<string> names) 
{ 
    var sb = new StringBuilder(); 
    sb.Append("select city,count(*) from table where user in ('"); 
    foreach (var name in name) 
    { 
     sb.Append("'"); 
     sb.Append(name); 
     sb.Append("',"); 
    } 
    sb.Remove(sb.Length-1,1); //remove trailing , 
    sb.Append(") GROUP BY city"); 

    return sb.ToString(); 
} 
같은 섹션에서이 ArrayList를 생성됩니다

"select city,count(*) from table where user in ("name1","name2","name3") GROUP BY city" 

을,

where in 절에는 100 항목 제한이 있습니다. 서브 세트가 그 길이와 같은 것이라면 사용자를 다른 테이블에 넣고 조인을 수행하는 것과 같은 더 나은 접근이 필요합니다. 실제로 사용자의 하위 집합이 다른 쿼리에 의해 동일한 데이터베이스에서 가져온 경우 게시하고 단일 쿼리를 올바르게 수행합니다.

편집 : 실제로 매개 변수화 된 명령으로 where user in 유형 쿼리를 수행하는 방법을 모르겠다면 SQL 주입에주의하십시오!

+0

SQL 문을 사용하여 이름의 데이터 테이블을 반환하는 함수를 만드는 방법이 필요하며 매개 변수는 도시 및 이름 목록이됩니다. –

+0

잘 SqlCommand에서 반환 된 문자열을 사용하면 완료! –

1

SQL 문은 같이해야합니다. 이 변수를 스토어드 프로 시저에 변수로 넣거나 코드 내에서 동적으로 Sql 문자열을 작성할 수 있습니다.

+0

매개 변수로 arraylist를 받아들이 기 위해 위에서 설명한 것과 같은 함수를 만들 수 있습니까? –

0

이렇게하는 한 가지 방법은 XML 매개 변수로 전달하는 것입니다. XML은 다음과 같습니다.

@Cities = '<xml><city>Chicago</city><city>New York</city></xml>' 

그리고 테이블로 선택 될 수 있습니다. 인구가 0 인 도시의 행을 반환한다는 점에서 매크로의 동작과 약간 다릅니다.

SELECT 
tempTable.item.value('.', 'varchar(50)') AS City, 
    COUNT(DISTINCT people) AS [Population] 
FROM @Cities.nodes('//city') tempTable(item) 
LEFT OUTER JOIN peopleTable 
ON tempTable.item.value('.', 'varchar(50)') = peopleTable.City 

위의 내용은 내가 처음 시도한 방식이므로 비평 해 주어서 기쁩니다!

내 습관적 인 접근 방식은 쉼표로 구분 된 목록으로 전달하고 분할 함수를 사용하여 조인 할 수있는 테이블 형식으로 가져 오는 것입니다. 분할 함수의 예는 here

1

입니다. SQL Server 2008을 사용하는 경우 테이블 변수를 입력 매개 변수로 사용하여 저장된 proc를 만들 수 있습니다. 그런 다음 proc 내부에서 입력 매개 변수 테이블에 조인하여 원하는 것을 얻을 수 있습니다.

1

table valued parameters을 사용할 수 있지만 SQL Server 2008 이상에서만 사용할 수 있습니다.

이름 수가 제한되어 있고 이전 버전의 SQL Server를 지원해야하는 경우 여러 매개 변수를 사용할 수 있습니다. 그렇게하면 SQL 인젝션으로도 안전합니다. 나는 당신이 무엇을 원하는 쿼리에 완전히 확실하지 않다, 그래서 당신의 코드를 기반으로 예를 들어주지 :

Public Shared Function GetCAData(ByVal employeeName() As String) As DataTable 
    Dim sql As StringBuilder = New StringBuilder() 
    sql.Append("SELECT EMPLID, EMPLNME, DISP_TYPE, BEGIN_DTE FROM Corr WHERE EMPLNME IN (") 

    Dim cmd As New SqlCommand() 
    For I As Integer = 0 To employeeName.Length - 1 
     sql.Append("@name").Append(I).Append(",") 
     cmd.Parameters.AddWithValue("@name" & I, employeeName(I)) 
    Next 

    sql.Remove(sql.Length - 1, 1).Append(")") 
    cmd.CommandText = sql.ToString() 

    Return GenericDataAccess.GetData(cmd) 
End Function 

(내 VB 조금 이상한 보이는 경우 미안 해요, 내가 그것을 사용하지 않습니다 더 이상)

실제로 동적 SQL 문을 빌드하지만 "동적"부분은 생성 된 매개 변수 이름의 모음 일뿐입니다. 허용되는 매개 변수의 최대 수는 2000 가지입니다.

관련 문제