2010-03-19 4 views
2

J'utilise la bibliothèque Enterprise, mais l'idée est la même. J'ai un SqlStringCommand et SQLADO.NET Batch Insert avec plus de 2000 paramètres

est construit en utilisant StringBuilder dans les formes de

"insert into table (column1, column2, column3) values (@param1-X, @param2-X, @parm3-X)"+" " 

où « X » représente une « boucle » environ 700 lignes

StringBuilder sb = new StringBuilder(); 
for(int i=0; i<700; i++) 
{ 
    sb.Append("insert into table (column1, column2, column3) values (@param1-"+i+", @param2-"+i, +",@parm3-"+i+") "); 
} 

suivie par la construction d'un objet de commande en y injectant tous les paramètres w/values.

Essentiellement, 700 lignes avec 3 paramètres, j'ai fini avec 2100 paramètres pour cette déclaration "un sql".

Il a fonctionné très bien pendant environ quelques jours et tout à coup j'ai eu cette erreur

=============================================================== 

A severe error occurred on the current command. The results, if any, should be discarded. 

at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) 
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 
at System.Data.SqlClient.SqlCommand.InternalExecuteNon 

Les pointeurs sont très appréciés.

+2

Si vous avez 2100 paramètres, vous devez repenser votre processus. –

+0

avec autant de données avez-vous atteint votre limite de DB? êtes-vous sur sql complet? – seanxe

+0

Bonjour Durlai et seanxe: J'importe un fichier texte avec 800 enregistrements, je fais un traitement pour me débarrasser de certains éléments, je construis un objet IList et je les importe dans ma base de données au milieu d'une transaction. Je peux parcourir les dossiers et en insérer un à la fois, pas de problème. En fait, je l'ai fait, cela fonctionne très bien, mais comme la liste peut augmenter au fil du temps, je voudrais exécuter les déclarations dans un aller-retour au lieu de 700 allers-retours. – Liming

Répondre

1

Je ne sais pas, mais il faut vérifier ceci: Hitting the 2100 parameter limit (SQL Server) when using Contains()

+0

Voilà durilai. Je viens de tester! si j'enlève un enregistrement et que le nombre de paramètres est 3 * 699 = 2097, c'est OK! Une fois qu'il atteint 2100, boom! – Liming

+0

J'ai aussi appris quelque chose de nouveau aujourd'hui, merci! –

+0

Dans le cas où d'autres veulent savoir. Voici les limites sur MSDN. Jamais pensé que je m'en soucierais jamais, mais maintenant je fais. http://msdn.microsoft.com/fr-fr/library/ms143432.aspx – Liming

2

Jetez un oeil à SQLBulkCopy. Il offrira probablement une meilleure solution à votre problème que votre approche actuelle.

+0

Merci Tim. J'ai regardé dedans, cependant, l'opération est au milieu d'une transaction, SQLBUlkCopy n'offre pas un paramètre pour la transaction. – Liming

1

Je pense que vous pouvez résoudre ce l'une des nombreuses façons

  1. inserts de lot pour 100 enregistrements

  2. Faites chaque insert comme sa propre commande avec une transaction enroulée autour de tous les inserts.

  3. Utiliser SQL copie en bloc

  4. Utilisez SSIS pour cela: les tâches ETL sont mieux fait à l'aide des outils ETL. Puisque vous utilisez SQL Server, vous pouvez facilement charger des fichiers de données dans SQL Server à l'aide de SSIS. Vous pouvez créer un package SSIS et l'exécuter depuis votre code C#.

+0

Merci Raj.# 2 est en quelque sorte ce que je fais maintenant, # 3, je ne peux pas le faire parce qu'il est dans le mdidle d'une transaction et SQLBulkCopy Class n'offre pas de paramètre pour la transaction. # 4 n'est pas une option car c'est un outil d'importation intégré dans notre application asp.net. Cependant, je pense que # 1 pourrait être le chemin à parcourir. Je vais essayer. – Liming

Questions connexes