2009-05-04 11 views
5

J'utilise SQL 2008 Express Edition et j'essaye de faire une insertion de plusieurs lignes à travers mon application C#.L'insertion de ligne multiple -> instruction dépasse le nombre maximum autorisé de 1000 valeurs de ligne

J'ai environ 100000 enregistrements qui doivent être insérés.

Bon tout va bien pour les 1000 premiers enregistrements alors que je reçois l'erreur:

« Le nombre d'expressions de valeur de la ligne dans l'instruction INSERT dépasse le nombre maximum autorisé de 1000 valeurs de la ligne. »

J'ai regardé mon type de données de colonne -> int, donc cela ne devrait pas être le problème. J'ai vérifié mon code et j'insère par pas de 500 enregistrements. Je l'ai donc googlé mais je n'ai rien trouvé d'utile. Quelqu'un peut-il expliquer pourquoi je reçois cette erreur et si possible comment le résoudre.

+1

Pouvez-vous nous montrer une partie de votre code? Ce message d'erreur ne doit apparaître que si vous utilisez des valeurs de ligne, par exemple. INSERT INTO ... VALUES (...), (...), (...) <- 3 lignes ici, et la limite est 1000. –

+0

avez-vous besoin d'un délai entre les requêtes d'insertion? – nlucaroni

+0

essayez-vous d'insérer une ligne à la fois? essayez d'appeler une procédure stockée pour faire toutes les insertions en même temps (si vous ne le faites pas déjà) – northpole

Répondre

5

Vous pouvez utiliser la classe SQLBulkCopy. Qui prend en charge le traitement par lots, les transactions et est plus efficace que les instructions d'insertion standard.

+0

"Si les tables source et de destination se trouvent dans la même instance SQL Server, il est plus facile et plus rapide d'utiliser un INSERT Transact-SQL. ... instruction SELECT pour copier les données. " Source: http://msdn.microsoft.com/fr-fr/library/s4s223c6.aspx Juste pour l'enregistrement. :) – ShdNx

0

c'est la façon dont mon code gère l'insertion multilignes

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; 
} 

Je vais vérifier la SqlBulkCopy. Peut-être que c'est une meilleure solution.

+0

Comme lassevk indiqué ci-dessus, la limite de cette méthode est de 1000 lignes. Vous voudrez peut-être regarder dans la syntaxe INSERT INTO tblName SELECT ... FROM otherTbl, car ce que vous faites semble venir presque directement d'une autre instruction SQL. Il n'y a pas de limite de ligne à ce sujet. – Eric

0

Vous pouvez prendre cette chose tout à ceci:

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!"); 
} 

également: vous devez savoir que Sql Server ne prend pas en charge mot-clé de MySql LIMIT. Il utilise TOP ou ROW_NUMBER à la place.

+0

Est-ce également applicable lorsque la première requête accède à une base de données mysql pour récupérer les données? J'ai besoin de transférer des données de la base de données mysql vers mon serveur sql local 2008 express. – Gerbrand

+0

Ah, je reçois votre convention de nommage maintenant. Votre extrait de code et le texte de la question donnent l'impression que tout passe par la même connexion, les mêmes noms ou aucun nom. Dans ce cas, vous devrez conserver les données sur votre client brièvement, et BULK_INSERT est de loin votre option la plus rapide. –

+0

Ou, avec beaucoup de chance, vous pourriez être en mesure de connecter le serveur mysql db à SQL comme une source de données ole db: http://developer.infi.nl/index.php?ID=6&article=6 –

Questions connexes