2011-03-13 3 views
0

필자에게 columnname, 열의 데이터 유형 및 최대 문자 길이를 제공하는 datatable이 있습니다. returntype은 목록이어야하며 하나의 목록에서 열 이름과 데이터 유형을 어떻게 연결할 수 있습니까? 도와주세요.하나의 목록에있는 데이터 테이블에서 데이터 유형을 반환하는 방법은 무엇입니까?

try 
     { 
      List<string> tablelist = new List<string>(); 
      DataTable dt; 
      conn.Open(); 
      SqlCommand cmd = new SqlCommand("SELECT column_name,data_type,character_maximum_length FROM "+ dbPropertiesobj.DBName +".information_schema.columns WHERE table_name = '"+ TableName+"' ", conn); 
      SqlDataAdapter sqlda = new SqlDataAdapter(cmd); 
      dt = new DataTable(); 
      sqlda.Fill(dt); 
      for (int i = 0; i < dt.Rows.Count; i++) 
      { 
       string dtrow = dt.Rows[i].ItemArray[0].ToString(); //gets only the columnname 
       tablelist.Add(dtrow); 
      } 
      return tablelist; // need the datatype and maximum character length along with the name. 
     } 
     catch (Exception ex) 
     { 
      return null; 
     } 

답변

1

이 코드는 계속 진행되고 있습니다. 필자는이 코드를 완벽하게 다시 작성했으며, 가장 짧은 코드 또는 최선의 방법은 아니지만 더 많은 것을 배우거나 작업 할 수있는 영역을 설명하기 위해 작성되었습니다.

예외 처리, 특히 사용시기와 용도에 대해 연구하십시오. 오류를 삼키는 try 블록을 작성하지 마십시오. 이 메쏘드가 null을 리턴한다면 당신은 무엇을 할 계획입니까? 테이블 이름이 나빴나요? 연결이 실패 했습니까? 사용자가 오류를 수정할 수도 있지만 그렇지 않을 수도 있습니다. 이제 아무도 그것이 무엇인지 알 수 없습니다.

null을 사용하여 수행 한 작업에 따라 여기에서도 오류가 발생한다는 것을 아무도 알지 못할 수도 있습니다. 이런 오류는 절대로 삼가하십시오. 오류가 발생한 지점에서 응용 프로그램이 실패해야합니다. 이것도 null을 돌려주는 것에주의 해주세요. 널 (null)을 리턴하고 나서 다른 작업을하면 나중에 어딘가에서 응용 프로그램이 실패 할 수 있으며 원래의 오류는 찾아서 수정하기가 훨씬 더 어려워집니다. 프레임 워크를 작성할 때 때때로이 스타일에서 null을 반환 할 수 있습니다. 일반 응용 프로그램의 경우 일반적으로 필요하지 않으며 거의 ​​좋은 아이디어가 아닙니다.

일반적으로 양질의 프로덕션 코드에는 예상 할 수있는 모든 것을 처리하기 위해 조건을 사용해야하므로 예외 처리가 거의 포함되지 않습니다. 당신이 예상 할 수없는 것은 대개 또한 처리 할 수 ​​없습니다. 리소스를 정리하기 위해 존재하는 많은 try ... finally 블록이있을 수 있지만 응용 프로그램에는 실제 시도 및 검색 검정이 거의 포함되어 있지 않아야합니다. 일반적으로 오류가 응용 프로그램이 종료되기 전에 사용자에게 알리는 최종 핸들러로 호출 스택을 전파하도록합니다.

다음은 여전히 ​​작성할 수있는 최상의 코드는 아닙니다. 나는 당신의 원본에 가깝게 유지하고 합리적이었고 명확하게하기 위해 몇 가지 단축키를 제거했습니다. 차이점을 연구하고 거기서 가십시오.

public class SomeClass 
{ 

    //Use parameters rather than accessing module level properties 
    private IList<ColumnInformation> GetColumnInformationForTable(string dbName, string tableName) 
    { 
     // Favor object oriented styles and meaningful names. Your method does not return a list of tables 
     // it returns a list of column meta data 
     List<ColumnInformation> columnInformations = new List<ColumnInformation>(); 

     // Avoid SQL conncatenation if at all possible. NEVER concatenate where parameters into SQL commands and NEVER EVER with single quotes. 
     // Here table name requires concatenation but the select parameter TableName does not. 
     string selectCmdString = "SELECT column_name,data_type,character_maximum_length FROM " + dbName + ".information_schema.columns WHERE table_name = @TableName"; 

     // Use parameters. Get everything ready first, don't open connections prematurely and only wrap error prone code in try blocks. 
     SqlCommand cmd = new SqlCommand(selectCmdString, conn); 
     SqlParameter tableNameParameter = new SqlParameter("@TableName", tableName); 
     cmd.Parameters.Add(tableNameParameter); 

     // Use a DataReader since you cannot modify this data anyway. 
     // This also shows an appropriate use of a try block to ensure a connection gets closed, 
     // but better yet, open your reader with the CommandBehavior set to close 
     // and get rid of this try block altogether 
     try 
     { 
      //Reconsider use of a module or global level connection. May be better to create a new here. 
      conn.Open(); 
      SqlDataReader reader = cmd.ExecuteReader(); 
      //Favor OOP styles rather than indexes and arrays and repeated calls to determine things like Rows.Count in a loop 
      while(reader.Read()) 
      { 
       // Favor explicit member access rather than index acess. 
       //YOUR HOMEWORK! Study DataReader access and rewrite the code below to handle possible nulls in length field. Use a method based on evaluating conditionals, DO NOT use a method based on a try block. 
       ColumnInformation columnInformation = new ColumnInformation(reader["column_name"].ToString(), reader["data_type"].ToString(), (int)reader["character_maximum_length"].ToString()); 
       columnInformations.Add(columnInformation); 
      } 
      reader.Close(); 
     } 
     finally 
     { 
      // The only reason to use the try is to make sure the connection gets closed here. A better approach 
      // is to use the CommandBehavior.CloseConnection option and get rid of the try finally block completely. 
      // But NEVER just wrap a bunch of code in try blocks arbitrarily, swallow any errors and return a null. 
      conn.Close(); 
     } 


     return columnInformations; 
    } 


} 

public class ColumnInformation 
{ 
    private string _columnName; 
    private string _dataType; 
    private int _columnLength; 

    public string ColumnName 
    { 
     get { return _columnName; } 
    } 

    public string DataType 
    { 
     get { return _dataType; } 
    } 

    public int ColumnLength 
    { 
     get { return _columnLength; } 
    } 

    public ColumnInformation(string columnName, string dataType, int columnLength) 
    { 
     _columnName = columnName; 
     _dataType = dataType; 
     _columnLength = columnLength; 
    } 
} 
+0

고맙습니다. ... 정말 도움이됩니다. 필자의 코딩 접근법과 표준에 대해서 다시 생각해 보도록 도와주었습니다. 지금 코드를 재정렬해야합니다. ThnQ – NewBie

1

왜 3-Tuple 개체 (예 : 3 개 값이있는 튜플) 목록이 적합하지 않은 이유는 무엇입니까? List를 선언하기위한 정확한 구문은 다음과 같을 것입니다.

Tuple.Create(column_name, datatype, max_length) 
관련 문제