2009-05-04 32 views
5

Estoy usando sql 2008 express edition y estoy tratando de hacer una inserción de varias filas a través de mi aplicación C#.Insertar varias filas -> instrucción excede el número máximo permitido de 1000 valores de fila

Tengo alrededor de 100000 registros que deben insertarse.

bien todo va bien para los primeros 1000 registros a continuación que estoy recibiendo el error:

"El número de expresiones de valores de filas en la instrucción INSERT excede el número máximo permitido de 1000 valores de fila."

Miré el tipo de datos de columna -> int, por lo que ese no debería ser el problema. Comprobé mi código y lo estoy insertando en pasos de 500 registros.

Así que busqué en Google pero no pude encontrar nada útil. ¿Alguien puede explicar por qué obtengo este error y, si es posible, cómo resolverlo?

+1

¿Puede mostrarnos algunos de sus códigos? Ese mensaje de error solo debería aparecer si está utilizando valores de fila, es decir. INSERT INTO ... VALUES (...), (...), (...) <- 3 filas aquí, y el límite es 1000. –

+0

¿necesita un retraso entre las consultas de inserción? – nlucaroni

+0

¿Estás tratando de insertar una fila a la vez? intente llamar a un procedimiento almacenado para hacer todas las inserciones a la vez (si todavía no lo hace) – northpole

Respuesta

5

Puede usar la clase SQLBulkCopy. Lo cual es compatible con lotes, transacciones y es más eficiente que las declaraciones de inserción estándar.

+0

"Si las tablas de origen y de destino están ubicadas en la misma instancia de SQL Server, es más fácil y rápido usar un INSERT de Transact-SQL ... instrucción SELECT para copiar los datos ". Fuente: http://msdn.microsoft.com/en-us/library/s4s223c6.aspx Solo para el registro. :) – ShdNx

0

Así es como mi código controla la inserción de múltiples

var count = "SELECT COUNT(*) as rowcount FROM table_mysql GROUP BY id"; 

var countReader = Retrieve(count); 
var countRows = 0; 
try 
{ 
    while (countReader.Read()) 
    { 
     countRows += int.Parse(countReader.GetValue(0).ToString()); 
    } 
} 
catch (Exception ex) 
{ 
    Log.LogMessageToFile("Import.cs -> table_mssql: " + ex.StackTrace + " /n" + ex.Message); 
} 
finally 
{ 
    if (countReader != null) { countReader.Close(); _crud.close_conn(); } 
} 

for (var a = 0; a < countRows;) 
{ 
    var sql = "SELECT id, traffic_id, dow, uu, imps, impsuu, otsw, otsm FROM table_mysql LIMIT " + a + ", " + (a + 500) + ""; 

    var reader = Retrieve(sql); 
    try 
    { 
     var builder = new StringBuilder(); 
     builder.Append(
      "SET IDENTITY_INSERT table_mssql ON;INSERT INTO table_mssql(id, traffic_id, dow, uu, imps, impsuu, otsw, otsm) VALUES "); 
     while (reader.Read()) 
     { 
      Application.DoEvents(); 
      try 
      { 
       builder.Append("(" + reader.GetValue(0) + ", " + reader.GetValue(1) + ", " + 
           reader.GetValue(2) + 
           ", " + reader.GetValue(3) + ", " + reader.GetValue(4) + 
           ", " + reader.GetValue(5) + ", " + reader.GetValue(6) + ", " + 
           reader.GetValue(7) + 
           "), "); 

      } 
      catch (Exception ex) 
      { 
       Log.LogMessageToFile("Import.cs -> table_mssql: " + ex.StackTrace + " /n" + ex.Message); 
      } 
     } 

     var sqlDB = builder.ToString(0, builder.Length - 2); 

     sqlDB += ";SET IDENTITY_INSERT table_mssql OFF;"; 
     if (!InsertDB(sqlDB)) 
     { 
      Log.LogMessageToFile("Import.cs -> table_mssql: No insert happend!"); 
     } 
    } 
    catch (Exception ex) 
    { 
     Log.LogMessageToFile("Import.cs -> table_mssql: " + ex.StackTrace + " /n" + ex.Message); 
     return false; 
    } 
    finally 
    { 
     if (reader != null) 
     { 
      reader.Close(); 
      _crud.close_conn(); 
     } 
    } 
    a = a + 500; 
} 

Voy a comprobar el SqlBulkCopy. Tal vez esa es una mejor solución.

+0

Como lassevk declaró anteriormente, el límite en ese método es 1000 filas. Es posible que desee examinar INSERT INTO tblName SELECT ... FROM other sintaxis Tbl, ya que lo que está haciendo parece venir casi directamente de otra instrucción SQL. No hay límite de fila en esto. – Eric

0

que puede tomar todo eso reduce a esto:

var sql = "SET IDENTITY_INSERT table_mssql ON;" 
     + "INSERT INTO table_mssql" 
     +  "(id, traffic_id, dow, uu, imps, impsuu, otsw, otsm)" 
     + " SELECT id, traffic_id, dow, uu, imps, impsuu, otsw, otsm " 
     + " FROM table_mysql;" 
     + "SET IDENTITY_INSERT table_mssql OFF;"; 

if (!InsertDB(sqlDB)) 
{ 
    Log.LogMessageToFile("Import.cs -> table_mssql: No insert happend!"); 
} 

también: usted debe saber que SQL Server no admite LIMIT palabra clave de MySQL. En su lugar, usa TOP o ROW_NUMBER.

+0

¿Esto también es aplicable cuando la primera consulta está accediendo a una base de datos mysql para recuperar los datos? Necesito transferir datos de la base de datos mysql a mi servidor sql local 2008 express. – Gerbrand

+0

Ah, obtengo su convención de nombres ahora. El fragmento de código y el texto de la pregunta hacen que parezca que todo está pasando por la misma conexión, nombres o sin nombres. En ese caso, deberá mantener los datos en su cliente brevemente, y BULK_INSERT es, de lejos, su opción más rápida. –

+0

O, con un montón de suerte, es posible que pueda conectar el servidor mysql db a sql como un origen de datos ole db: http://developer.infi.nl/index.php?ID=6&article=6 –

Cuestiones relacionadas