2014-09-15 8 views
1

나는의 SQL Server Compact에 MS 액세스에서 데이터를 마이그레이션 할 의도 C# 응용 프로그램이 4.0SQL 서버 세륨 4.0 오류 2700

가 많은 양의 데이터이며, 같은 내가 병렬의 큰 숫자를 사용하고 있습니다. Foreach 문을 사용하여 데이터를 살펴보고 SQL Server CE 데이터베이스에 많은 수의 읽기 및 쓰기가 있지만 액세스 데이터베이스에서 한 번만 읽습니다.

그것은 잘 좋은 반 시간 동안 실제로 데이터베이스가 작성됩니다 (I 파일 크기에서 이것을 볼 수 있으며, 에러가 발생한 후 확인) 그러나 결국 나는 집계 예외가 던져

정말 작동

그 내부 예외는 다음과 같습니다

SQLServerCEException : 너무 많은 세션이 열려, NativeError 27000

내가 검색 한 구글과 내가 찾은 유일한 해결책에 명시 적으로 가까운 모든 명령했다 s, 연결 및 어댑터를 사용할 수 있습니다.

내가 데이터베이스와 통신하는 데 사용하는 세 가지 방법은 다음과 같습니다

/// <summary> 
/// Executes a single INSERT, UPDATE, DELETE or other Sql Command that modifies the schema or data of the database 
/// </summary> 
/// <param name="sql">The command to execute</param> 
/// <param name="parameters">Any parameters in the command</param> 
public void ExecuteCommand(string sql, SqlServerCeParameter[] parameters) 
{ 
    //print debug statements if necessary 
    if (_outputSqlStatementsToFile == true) PrintSqlDebuggingInformation(sql, parameters); 

    //create a new connection using the connection string 
    using (var connection = new SqlCeConnection(_connectionString)) 
    { 
     //create the command that will execute the Sql 
     using (var command = new SqlCeCommand(sql, connection)) 
     { 
      //add any parameters 
      if (parameters != null) command.Parameters.AddRange(parameters.Select(p => p.ParameterBehind).ToArray()); 

      try 
      { 
       //open the connection 
       connection.Open(); 

       //execute the command 
       command.ExecuteNonQuery(); 
      } 
      catch (SqlCeException ex) 
      { 
       //only catch if the native error is the duplicate value exception otherwise throw as normal 
       if (ex.NativeError != 25016) throw; 
      } 
      finally 
      { 
       //explicitly close command 
       command.Dispose(); 
      } 
     } 
     //explicitly close the connection 
     connection.Close(); 
    } 
} 

/// <summary> 
/// Executes a query that returns a single value, for example a COUNT(*) query 
/// </summary> 
/// <typeparam name="T">The type of the value returned by the query, for example COUNT(*) would be an Integer</typeparam> 
/// <param name="sql">The query to execute</param> 
/// <param name="parameters">Any parameters in the query</param> 
/// <returns>A single value cast to type T</returns> 
public T ExecuteQuery<T>(string sql, SqlServerCeParameter[] parameters) 
{ 
    //print debug statements if necessary 
    if (_outputSqlStatementsToFile == true) PrintSqlDebuggingInformation(sql, parameters); 

    //the result 
    T result; 

    //create a new connection using the connection string 
    using (var connection = new SqlCeConnection(_connectionString)) 
    { 
     //create the command that will execute the Sql 
     using (var command = new SqlCeCommand(sql, connection)) 
     { 
      //add any parameters 
      if (parameters != null) command.Parameters.AddRange(parameters.Select(p => p.ParameterBehind).ToArray()); 

       //open the connection 
       connection.Open(); 

       //execute the command and cast the result to the type given to the method 
       result = (T)command.ExecuteScalar(); 

       //explicitly dispose the command 
       command.Dispose(); 
     } 
     connection.Dispose(); 
    } 
    //return the result 
    return result; 
} 

/// <summary> 
/// Executes a query that returns a list of rows in a data table 
/// </summary> 
/// <param name="sql">The query to execute</param> 
/// <param name="parameters">Any parameters in the query</param> 
/// <returns>A data table of rows matching the query</returns> 
public DataTable ExecuteQuery(string sql, SqlServerCeParameter[] parameters) 
{ 
    //print debug statements if necessary 
    if (_outputSqlStatementsToFile == true) PrintSqlDebuggingInformation(sql, parameters); 

    //the returnable data table 
    var table = new DataTable(); 

    //create a new connection using the connection string 
    using (var connection = new SqlCeConnection(_connectionString)) 
    { 
     //create the command that will execute the Sql 
     using (var command = new SqlCeCommand(sql, connection)) 
     { 
      //add any parameters 
      if (parameters != null) command.Parameters.AddRange(parameters.Select(p => p.ParameterBehind).ToArray()); 

      //create an adapter to which will fill the data table that is to be returned 
      using (var adapter = new SqlCeDataAdapter(command)) 
      { 
       //open the connection 
       connection.Open(); 

       //fill the table using the adapter 
       adapter.Fill(table); 

       //explicitly dispose the adapter 
       adapter.Dispose(); 
      } 
      command.Dispose(); 
     } 
     connection.Dispose(); 
    } 
    //return the result 
    return table; 
} 

이 방법은 셀 수없이 많은 시간이라고하며 오류가 발생하는 첫 번째 방법에서 command.ExecuteNonQuery()에 일반적입니다.

누구에게 의견이 있습니까?

답변

1

각 SQL 문에 대한 연결을 열거 나 닫지 않는 것이 좋습니다. 대신에 그러한 수의 연결을 열면 얼마나 많은 병렬 프로세스가 하나씩 있는지를 알 수 있습니다. 마이그레이션 시작과 종료 후 연결을 엽니 다. 동일한 열린 연결을 사용하여 많은 SQL 문을 발행 할 수 있습니다.

또한이 같은 간단한 연결 풀 구현을 사용할 수 있습니다 : "Creating a custom database connection pool - CodeProject는"

이것은 또한 마이그레이션 성능을 향상시킵니다.

+0

당신은 C#에서 연결 풀링을 알고 계신가요? 많은 기대는하지 않습니다. 그래서 이것이 '델파이'라면 OP의 필요성에 도움이 될 것이라고 제안합니다. 좋은 제안이지만 C#은 연결 풀링을 다르게 처리합니다. – MethodMan