문제

Calls Calls, Location, Emergency_Type가있는 Call이라는 데이터베이스 테이블이 있으며 구급대 원, 경찰 및 소방관의 세 가지 비상 사태가 있습니다. Windows 양식에서 나는 'Paramedics', 'Police', '소방관'을 만들었고 사용자 선택을 충족하는 모든 테이블 열을 검색하고 싶습니다.

나는 함수를 만들었다 :

public static DataTable GetHistory(DateTime from, DateTime to, bool paramedics, bool police, bool firefighters)
    {
        string select =
            "SELECT call_time, location, emergency_type where call_time between @from AND @to AND";
        if(paramedics)
        {
            select += " emergency_type = 'paramedics' ";
        }
        if(paramedics && police)
        {
           select +=" emergency_type = 'paramedics' OR emergency_type = 'police';
        }
        ...

    }

그러나이 코드는 30 종류의 비상 사태가 있으면 30이 있기 때문에 매우 더러워 보입니다! 조합과 나는 모든 if 진술을 작성하기 전에 늙어갈 것입니다.

선택한 검색 조건을 충족하는 데이터를 검색하기위한 실습을 공유하더라도 감사 할 수 있습니다.

감사!

도움이 되었습니까?

해결책

긴급 _type를 문자열로 사용해야한다면 부울을 통과하는 대신 비상 유형의 텍스트 표현이 포함 된 목록을 보낼 수 있습니다. 예를 들어 위의 코드를 조정하려면 메소드 서명을

public static DataTable GetHistory(DateTime from, DateTime to, List<string> types)
{
 ..
}

그런 다음 이와 같이 보이는 목록을 전달하십시오 (예 :

List<string> types = 
  new List<string> { "paramedics" };

or 

List<string> types = 
  new List<string> { "paramedics", "police" };

그런 다음 쿼리를 조정하여 WHERE 절에서 SQL을 사용합니다. 다음으로 문자열 목록을 쉼표로 분리 된 문자열로 변환합니다.

string values = "'paramedics', 'police'"

값 변수를 만드는 간단한 방법은 사용하는 것입니다.

string values = string.Empty;
            types.ForEach(s =>
            {
               if (!string.IsNullOrEmpty(values))
                   values += ",";
               values += string.Format("'{0}'", s);

            });

그건 그렇고, 당신은 매개 변수화 된 명령을 사용하여 SQL 주입을 피할 수 있습니다. 문자열이 있으면 단순히 할 수 있습니다

string select =
 "SELECT call_time, location, emergency_type where call_time between @from AND @to AND emergency_type IN " + values

다른 팁

이것은 이것을하는 더러운 방법입니다.

string select = "SELECT call_time, location, emergency_type where call_time between @from AND @to AND (1=0";

if(paramedics) { select += " OR emergency_type = 'paramedics' "; }
if(police)     { select += " OR emergency_type = 'police'"; }
if(xyz)        { select += " OR emergency_type = 'xyz'"; }

select += ")";

일부 불쾌한 취약점에 기여할 수 있으므로 문자열 연결은 피해야합니다. 프로그래밍 방식 액세스 측면에서 모범 사례를 찾고 있다면 여기서 모범 사례는 매개 변수화 쿼리를 사용하는 것입니다.

If you want to be cheap, then make the in clause take a parameter, and concatenate that string together from the list of checked checkboxes, and pass that as the value of the parameter for the in clause. 다음과 같습니다.

where ... and emergency_type in (?)

이를 수행하는 다른 방법은 확인 된 확인란의 수를 계산하고 IN 절에 매개 변수 목록을 작성하여 다음과 같이 보이는 것입니다.

where ... and emergency_type in(?,?...) -- as many params as there are checked checkboxes.

이 중 하나는 잘할 것입니다. 이러한 유형의 쿼리를 사용하면 내 자신의 SQL 생성자 메소드를 빌드하고 내부 매개 변수 수와 데이터 유형을 유지하고 SQL을 동적으로 빌드 한 다음 알려진 좋은 매개 변수 목록으로 준비하십시오. .

LINQ 학습을 볼 수 있습니다.

사용자의 비교 값 목록 (@emergencyList)을 빌드하고 포함 된 연산자를 사용하여 매개 변수화 쿼리와 함께 SQL을 사용하십시오.

SELECT call_time, 
       location, 
       emergency_type 
where call_time between @from AND @to 
  AND CONTAINS( Emegency_Type, @EmergencyList )
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top