2012-12-24 2 views
2

나는 이제 성능 보안 및 가능한 다른 모든 측면에 대한 내 수업을 평가하십시오 수있는 하나의 매개 변수화 된 쿼리 클래스적절한 매개 변수화 된 쿼리 클래스 SQL 서버

내 쿼리를 캡슐화하기 시작입니까?

의견이 있으십니까?

여기 내 선택 클래스

public static DataSet cmd_SelectQuery(string srCommandText, List<string> lstParameterNames, List<string> lstParameters) 
{ 
    DataSet dsCmdPara = new DataSet(); 
    try 
    { 
     using (SqlConnection connection = new SqlConnection(DbConnection.srConnectionString)) 
     { 
      using (SqlCommand cmd = new SqlCommand(srCommandText, connection)) 
      { 
       cmd.CommandType = CommandType.Text; 
       for (int i = 0; i < lstParameterNames.Count; i++) 
       { 
        cmd.Parameters.AddWithValue(lstParameterNames[i], lstParameters[i]); 
       } 
       connection.Open(); 
       using (SqlDataAdapter sqlDa = new SqlDataAdapter(cmd)) 
       { 
        sqlDa.Fill(dsCmdPara); 
        return dsCmdPara; 
       } 
      } 
     } 
    } 
    catch (Exception E) 
    { 
     csPublicFunctions.insertIntoTblSqlErrors(srCommandText + " " + E.Message.ToString()); 
    } 
    return dsCmdPara; 
} 

그리고 여기 내 업데이트, 삭제 클래스

public static void cmd_UpdateDeleteQuery(string srCommandText, List<string> lstParameterNames, List<string> lstParameters) 
{ 
    try 
    { 
     using (SqlConnection connection = new SqlConnection(DbConnection.srConnectionString)) 
     { 
      using (SqlCommand cmd = new SqlCommand(srCommandText, connection)) 
      { 
       cmd.CommandType = CommandType.Text; 
       for (int i = 0; i < lstParameterNames.Count; i++) 
       { 
        cmd.Parameters.AddWithValue(lstParameterNames[i], lstParameters[i]); 
       } 
       connection.Open(); 
       cmd.ExecuteNonQuery(); 
      } 
     } 
    } 
    catch (Exception E) 
    { 
     csPublicFunctions.insertIntoTblSqlErrors(srCommandText + " " + E.Message.ToString()); 
    } 
} 

감사 답변

에 대한 많은
+0

무엇 당신의 매개 변수 중 하나가 문자열이 아닌 경우? (예 :'select * from table where ID = @ tableID' 및 ID는 숫자 필드 임) – Steve

+0

문자열 유형 대신 매개 변수를 전달하는 방법은 무엇입니까? –

+0

필자는 분명히 패스 할 수 없다 : D 제안 클래스를 대답으로 게시 할 수있다. – MonsterMMORPG

답변

1

코드는 유효하고 올바른 그대로 표시됩니다. 당신은 피드백을 요청 했으므로 다음과 같은 점이 있습니다.

(1) 매개 변수를 작성하는 코드에서 데이터 유형을 지정하는 것이 좋습니다. Fill 메서드는 당신을 위해처럼

for (int i = 0; i < lstParameterNames.Count; i++) 
{ 
    var parameter = cmd.Parameters.AddWithValue(lstParameterNames[i], lstParameters[i]); 
    parameter.SqlDbType = SqlDbType.NVarChar; // or whatever type you need 
} 

(2) 당신은 명시 적으로 개방/연결을 종료 할 필요가 없습니다.

connection.Open(); 
using (SqlDataAdapter sqlDa = new SqlDataAdapter(cmd)) 
{ 
    sqlDa.Fill(dsCmdPara); 
    connection.Close(); 
    return dsCmdPara; 
} 

(3) 만, 하나 개의 테이블이 데이터 집합 대신 DataTable을 사용하려고하는 경우. 그것은 더 빠르고 덜 복잡 할 것입니다.

(4) 이것은 스타일 포인트 일 뿐이지 만 명시 적으로 연결을 닫으면 매우 유용합니다. 닫는 중에 예외가있는 경우 줄 번호 (pdb를 통해)를 사용하는 것이 매우 유용합니다. 또한 사용을 잊어 버렸을 때 연결이 누출되지 않도록 도와줍니다.


편집 내가 점 (4)을 명확히 할

폐쇄에 연결이 정리가 예외를 발생시킨 때 가정합니다. 연결을 명시 적으로 닫지 않으면 다른 작업을 수행하는 Dispose 메서드에서 예외가 발생합니다. 이로 인해 I이 문제를 일으켰습니다.

간단한 예를 들어보십시오. 정리해야 할 기본 리소스 (Dispose의 전체 이유)가 있으며 예외가 발생합니다.

public class Resource: IDisposable 
{ 
    public void Close() 
    { 
     CleanupMemory(); 
    } 

    private void CleanupMemory() 
    { 
     throw new Exception(); 
    } 

    public void Dispose() 
    { 
     CleanupMemory(); 
    } 
} 

두 가지 다른 방식의 (정리) 스택 추적은 다음과 같습니다

using (var r = new Resource()) 
{ 
    r.Close(); 
} 

    at ConsoleApplication1.Resource.CleanupMemory() in Program.cs:line 31 
    at ConsoleApplication1.Resource.Close() in Program.cs:line 26 
    at ConsoleApplication1.Program.Main(String[] args) Program.cs:line 16 

첫 번째 예에서

using (var r = new Resource()) 
{ 

} 


    at ConsoleApplication1.Resource.CleanupMemory() in Program.cs:line 35 
    at ConsoleApplication1.Resource.Dispose() in Program.cs:line 40 
    at ConsoleApplication1.Program.Main(String[] args) in Program.cs:line 18 

대, 내 전화 닫기 예외를 발생시킨 것을 알고있다 , 나는 디버깅을 시작할 곳이있다. 예외가 throw 된 경우에만 예외의 정보를 완전히 의존해야합니다. 나는 다른 문맥이 없습니다. 대부분의 예외 메시지는 명확하지 않습니다. :)

둘 다 완전히 다릅니다.

에릭

+0

제안에 감사드립니다. 스탠드는 내부에서 오류가 발생했다고 가정합니다. 연결을 닫지 않겠습니까? 또한 내 시스템은 데이터 세트로 많은 낭비가 된 것 같아요. 거의 99 %의 시간 만 내가 1 테이블 만 선택한다고해도 ^^ 그런 식으로 만들었습니다. – MonsterMMORPG

+0

연결이 닫히지 않을 것이지만 예외는 없을 것입니다. using 블록에 의해 생성 된 코드 내부에서 발생 될 수 있습니다. 이런 일이 발생하면 로컬 변수에 액세스 할 수 없으므로 디버깅이 더 어려워집니다. –

+0

"연결이 닫히지 않습니다." – MonsterMMORPG

2

내가 이걸 쓰고 있기 때문에 두 빠른 제안 전화. 객체의

  1. 테이크, 매개 변수 목록이 방법이 좀 더 자연 사용하는 방법을 하듯 PARAMS 객체 []에서 촬영하지 문자열
  2. .
+0

감사하지만 "매개 변수 목록으로 사용하면 params object []가 무엇을 의미합니까? 각 개체가 개체 목록이어야한다는 의미입니까? – MonsterMMORPG

+0

Params를 사용하면 다음과 같은 작업을 수행 할 수 있습니다. 쿼리 ("select * from order where id = {0} 및 status = {1}", id, 5); 알림 매개 변수를 넣으려면 새 목록을 만들 필요가 없었습니다. –

-1
public DataTable Get_DTable(String Query, Dictionary<String, String> Parameters) 
    { 
     try 
     { 
      using (con = new SqlConnection(cls_Connection.URL())) 
      { 
       if (con.State == 0) 
        con.Open(); 
       using (cmd = new SqlCommand(Query, con)) 
       { 
        foreach (KeyValuePair<string, string> item in Parameters) 
        { 
         cmd.Parameters.AddWithValue(item.Key, item.Value); 
        } 

        using (da = new SqlDataAdapter(cmd)) 
        { 
         using (dt = new DataTable()) 
         { 
          da.Fill(dt); 
          if (dt.Rows.Count > 0) 
          { 
           return dt; 
          } 
         } 
        } 
       } 
      } 
     } 
     catch (Exception exp) 
     { 
      MessageBox.Show(exp.Message, 
          "Information", 
          MessageBoxButtons.OK, 
          MessageBoxIcon.Information); 
     } 
     return null; 
    } 
관련 문제