2016-06-08 2 views
0

아래 코드는 내 DataTable에 대해 처음 실행될 때와 똑같이 작동합니다. 데이터 테이블이로드되면 지정된 문자열을 사용하여 지정된 모든 열 데이터가 업데이트됩니다. 모든 것이 적절하게 닫혀 있습니다 (아마도 삭제 될 것입니다).DataTable ArgumentOutOfRangeException

public void AppendKeyColumn(string appendText, params string[] columnNames) 
{    
    string columns = ""; 

    // Create a list of the columns to use, comma separated. 
    for (int column = 0; column < columnNames.Length; column++) 
    { 
     if ((column + 1) == columnNames.Length) 
     { 
      columns += columnNames.ElementAt(column); 
     } 
     else 
     { 
      columns += columnNames.ElementAt(column) + ", "; 
     } 
    } 

    // SQL Statement for querying the file. Change after FROM for proper table name. 
    string sql = "SELECT " + columns + " FROM " + TableName; 

    // Using to create a command variable (so it will be properly disposed after block execution). 
    using (OleDbCommand cmd = new OleDbCommand(sql, Connection)) 
    { 
     // Open a connection to the data source. 
     Connection.Open(); 

     // Open the datareader, load the datatable with the data in the reader, and then close the reader. 
     Data = cmd.ExecuteReader(); 
     Table.Load(Data); 
     Data.Close(); 

     foreach (string column in columnNames) 
     { 
      // Run UPDATE statement to append text to end of column name. 
      for (int row = 0; row < Table.Rows.Count; row++) 
      { 
       string sql2 = "UPDATE " + TableName + " SET " + column + " = @newName WHERE " + 
         column + " = @oldName"; 

       using (OleDbCommand cmd2 = new OleDbCommand(sql2, Connection)) 
       { 
        string oldString = Table.Rows[row][0].ToString();       
        string newString = oldString.Remove(oldString.Length - 1); 
        newString = newString.Insert(newString.Length, appendText); 

        cmd2.Parameters.AddWithValue("@newName", newString); 
        cmd2.Parameters.AddWithValue("@oldName", oldString); 

        if (!Equals(oldString.Substring(oldString.Length-1, 1), appendText)) 
        { 
         cmd2.ExecuteNonQuery(); 
        } 
       } 
      } 
     } 

     Table.Clear(); 
     Connection.Close(); 
    } 
} 

이 코드를 두 번째로 실행할 때 내 문제가 있습니다. 같은 테이블에서 다시 호출하면 다음 오류가 발생합니다 (이 줄에서 string newString = oldString.Remove(oldString.Length - 1);). DataTable에는이 열에 대해 호출되는 빈 문자열이 없어야합니다. 첫 번째 호출에서 DataTable로드하고 예상대로 작동합니다. 두 번째 실행에서는 DataTable의 행 수가 올바르게 표시되지만 물리적으로 비어있는 것으로 보입니다.

InnerException: 
System.ArgumentOutOfRangeException: StartIndex cannot be less than zero. 
Parameter name: startIndex 
    at System.String.Remove(Int32 startIndex) 

나는 아마도 내가 기본적인 것을 간과하고 있다고 가정하고 있지만, 누군가 올바른 방향으로 향하게 할 수 있습니까?

+0

그것을 따라서 0으로이 오류를 던지고있다 oldstring.length 가지게됩니다 열 값 중 하나가 null의 표에서와 같이 보이는 좋은 정리를 만들 수있는 방법이있다? – Akhilesh

답변

1

귀하의 문제 솔기 : 심도도받지 않고, 한 가지 당신이이 해결 할 수있는 라인 Table.Load(Data);

그리고 여기가
string sql = String.Format("SELECT ({0}) FROM {1};", String.Join(", ", columnNames), TableName);

+0

이 부분이 수정되었습니다. 새 DataTable을 다시 사용하려면 먼저 인스턴스를 만들어야하는 이유는 무엇입니까? 나는 객체에서 한번만 생성 한 다음 다시 Clear() 및 Load()를 다시 수행 할 수 있다는 가정 아래에있었습니다. –

+1

DataTable은 가비지 수집을 할 때 변덕스러운 구성 요소입니다. DataTable에 이미로드 된 것으로 간주되므로 두 번째로로드되지 않습니다. –

0

빈 문자열이 실행 중입니다. Table 개체, 당신은 전에 Table = new DataTable;를 추가, 그래서 만약 내가, 그것이 DataTable을 가정하자로 인한 될

var newString = ""; 
if(oldString != String.Empty) 
{ 
    newString = oldString.Remove(oldString.Length - 1); 
} 
+0

죄송합니다. 분명히하기 위해 게시물을 편집 하겠지만 열에는이 함수를 실행하는 빈 문자열이 없습니다. 빈 문자열이 있어서는 안됩니다. 첫 번째 실행에는 실제로 DataTable에 레코드가 있습니다. 두 번째 실행에서는 올바른 수의 행을 표시하지만 실제로 값을로드하지 않는 것 같습니다. –

관련 문제