SqlCommand() la méthode ExecuteNonQuery() tronque le texte de la commande
Je suis en train de construire une coutume db utilitaire de déploiement, j'ai besoin de lire des fichiers texte contenant des scripts sql et de les exécuter sur la base de données.
Assez facile de trucs, c'est très bien.
Cependant j'ai rencontré un problème, le contenu du fichier sont lues correctement et entièrement, mais une fois passé dans le SqlCommand, puis exécuté avec SqlCommand.ExecuteNonQuery seulement une partie du script est exécuté.
J'ai tiré jusqu'Profiler et a confirmé que mon code n'est pas en passant toutes les du script.
private void ExecuteScript(string cmd, SqlConnection sqlConn, SqlTransaction trans)
{
SqlCommand sqlCmd = new SqlCommand(cmd, sqlConn, trans);
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandTimeout = 9000000; //for testing
sqlCmd.ExecuteNonQuery();
}
//I call it like this, readDMLScript contains 543 lines of T-SQL
string readDMLScript = ReadFile(dmlFile);
ExecuteScript(readDMLScript, sqlConn, trans);
Ce personnage est le script tronquée?
comment le
comment bien texte en êtes-vous de lire à partir du fichier, en octets?
Merci pour l'aide de Marc, j'ai été en utilisant un lecteur de Flux. Je vais passer à Système.IO.Fichier.ReadAllText(nom de fichier) pour des raisons de clarté. Maintenant, sur la question, je me doutais bien que le script a été foiré parce que lors de l'exécution à l'aide de la SqlCommand exceptions relatives à la syntaxe du script ont été soulever alors qu'il fonctionnait bien dans Sql Management Studio. Il semble que j'ai eu quelques traumatismes à la tête ce matin, il s'avère que le script n'est pas tronqué.
Les exceptions sont toujours en me tenant le dos. Savez-vous pourquoi quelque chose comme ceci :.Les données.SqlClient.SqlException: syntaxe Incorrecte près de 'GO'. Syntaxe incorrecte près de 'GO'. Syntaxe incorrecte près de 'GO'. Pour être visible sous la SqlCommand, mais pas sous Sql Management Studio lors de l'exécution d'un script?
comment le
ReadFile
méthode de travail? Êtes-vous à 200% que c'est de ne pas sauter les quelques caractères, peut-être?? Pourquoi ne pas simplement utiliser System.IO.File.ReadAllText(filename)
??comment bien texte en êtes-vous de lire à partir du fichier, en octets?
Merci pour l'aide de Marc, j'ai été en utilisant un lecteur de Flux. Je vais passer à Système.IO.Fichier.ReadAllText(nom de fichier) pour des raisons de clarté. Maintenant, sur la question, je me doutais bien que le script a été foiré parce que lors de l'exécution à l'aide de la SqlCommand exceptions relatives à la syntaxe du script ont été soulever alors qu'il fonctionnait bien dans Sql Management Studio. Il semble que j'ai eu quelques traumatismes à la tête ce matin, il s'avère que le script n'est pas tronqué.
Les exceptions sont toujours en me tenant le dos. Savez-vous pourquoi quelque chose comme ceci :.Les données.SqlClient.SqlException: syntaxe Incorrecte près de 'GO'. Syntaxe incorrecte près de 'GO'. Syntaxe incorrecte près de 'GO'. Pour être visible sous la SqlCommand, mais pas sous Sql Management Studio lors de l'exécution d'un script?
OriginalL'auteur H. Abraham Chavez | 2010-03-16
Vous devez vous connecter pour publier un commentaire.
Yep, tout le monde tape cette accrocher la première fois qu'ils commencent à envoyer le contenu de fichiers de script SQL pour la base de données.
GO
n'est pas une commande T-SQL. C'est la fin-du-lot marqueur reconnu par tous les Microsoft interactive SQL outils de Gestion (Studio, isql, osql). Pour les manipuler, vous devrez écrire votre propre analyseur de briser tous les blocs de texte dans le fichier entreGO
déclarations et de les nourrir à la base de données en tant que commandes distinctes.Comment mettre en œuvre votre analyseur est à vous. Il pourrait être simple (lire chaque ligne à un moment de détecter les lignes qui consiste en rien mais
GO
et des espaces) ou complexe (tokenising tous les états et de travail si unGO
est une véritable déclaration ou un peu de texte à l'intérieur d'une chaîne, ou un commentaire multi-lignes).Personnellement, je suis allé avec la première option. Il gère 99% de tous les fichiers SQL jamais vous êtes susceptible de rencontrer avec pas de chichi. Si vous voulez aller jusqu'au bout et d'écrire un tokeniser, je suis sûr que beaucoup de gens l'ont fait déjà, il suffit de Google.
Exemple:
IDENTITY_INSERT est prévu pour une utilisation dans l'importation de données des scripts, donc c'est une bonne solution. Personnellement, cependant, je voudrais utiliser SSIS pour importer des données.
Le problème que j'ai maintenant est de savoir si j'exporter un script à partir de SSMS commençant par 'SET IDENTITY_INSERT <table_name>', il ne sera pas suffisant pour l'utilisation de votre code? N'aurai-je pas besoin pour l'exécution de cette commande avant chaque insertion?
IDENTITY_INSERT reste ensemble jusqu'à ce que vous l'éteignez, vous n'avez qu'à régler qu'une seule fois. Quel problème rencontrez-vous avec votre script exactement?
Je vais avoir ce problème: stackoverflow.com/questions/7714812/...
OriginalL'auteur
J'ai trouvé le code ci-dessous lors de la recherche de la réponse à cette question:
http://blogs.msdn.com/b/onoj/archive/2008/02/26/incorrect-syntax-near-go-sqlcommand-executenonquery.aspx
Avantages: Il est court et simple à comprendre et a parfaitement fonctionné pour mes besoins.
Inconvénients: Il est moins efficace que basé sur les Flux de solutions et est sensible à la casse (j'.e "ALLER" de ne pas "aller").
OriginalL'auteur
ExecuteNonQuery dans SMO travaille avec des lots:
http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.database.executenonquery.aspx
OriginalL'auteur
Réponse basée sur les commentaires sous le post original:
GO est un marqueur de Gestion de Studio /osql /isql. Il dit d'envoyer un lot de commandes de SQL Server. Dans votre utilitaire, vous devez séparer les données d'entrée en utilisant ALLER comme un séparateur et d'envoyer chaque élément individuellement (sans la commande GO)
OriginalL'auteur
C'est ce que nous utilisons 🙂
OriginalL'auteur
J'ai fini par écrire une implémentation de l'StringReader pour ce faire.
Il gère:
Par conséquent, il ne détectera que le mot-clé ALLER lorsqu'il est utilisé comme un élément de séparation de lot. Cela signifie qu'il divise le texte SQL correctement.
Il gère aussi si vous avez ajouté un sql terminator (point-virgule) pour le mot ALLER
Vous pouvez trouver le code pour qu'il ici:
Vous l'utilisez comme suit:
OriginalL'auteur