104 votes

Comment puis-je exécuter un grand script SQL (avec les commandes GO) à partir de c#?

J'ai besoin d'exécuter un ensemble d'instructions sql (création d'un groupe de tables, vues et procédures stockées) à partir d'un programme c#.

Ces déclarations doivent être séparés par "ALLER", mais SqlCommand.ExecuteNonQuery() n'aime pas "ALLER" des déclarations. Ma solution, qui, je suppose, je vais poster pour référence, a été de diviser la chaîne sql sur "GO" des lignes, et la réalisation de chaque lot séparément.

Est-il un moyen plus facile/mieux?

122voto

Jon Galloway Points 28243

Utiliser SQL Server Management Objects (SMO) qui comprend ALLER séparateurs. Voir mon blog ici: http://weblogs.asp.net/jgalloway/archive/2006/11/07/Handling-_2200_GO_2200_-Separators-in-SQL-Scripts-2D00-la-facile-moyen.aspx

Exemple de code:

public static void Main()    
{        
  string scriptDirectory = "c:\\temp\\sqltest\\";
  string sqlConnectionString = "Integrated Security=SSPI;" +
  "Persist Security Info=True;Initial Catalog=Northwind;Data Source=(local)";
  DirectoryInfo di = new DirectoryInfo(scriptDirectory);
  FileInfo[] rgFiles = di.GetFiles("*.sql");
  foreach (FileInfo fi in rgFiles)
  {
        FileInfo fileInfo = new FileInfo(fi.FullName);
        string script = fileInfo.OpenText().ReadToEnd();
        SqlConnection connection = new SqlConnection(sqlConnectionString);
        Server server = new Server(new ServerConnection(connection));
        server.ConnectionContext.ExecuteNonQuery(script);
   }
}

Si cela ne fonctionne pas pour vous, consultez Phil Haack, à la bibliothèque du qui gère qui: http://haacked.com/archive/2007/11/04/a-library-for-executing-sql-scripts-with-go-separators-and.aspx

39voto

Blorgbeard Points 38991

C'est ce que j'ai frappé ensemble pour résoudre mon problème immédiat.

private void ExecuteBatchNonQuery(string sql, SqlConnection conn) {
    string sqlBatch = string.Empty;
    SqlCommand cmd = new SqlCommand(string.Empty, conn);
    conn.Open();
    sql += "\nGO";   // make sure last batch is executed.
    try {
        foreach (string line in sql.Split(new string[2] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries)) {
            if (line.ToUpperInvariant().Trim() == "GO") {
                cmd.CommandText = sqlBatch;
                cmd.ExecuteNonQuery();
                sqlBatch = string.Empty;
            } else {
                sqlBatch += line + "\n";
            }
        }            
    } finally {
        conn.Close();
    }
}

Il nécessite de PASSER des commandes sur leur propre ligne, et ne pourra pas détecter bloc de commentaires, si ce genre de chose obtiendrez split, et de provoquer une erreur:

ExecuteBatchNonQuery(@"
    /*
    GO
    */", conn);

11voto

tbreffni Points 3031

Vous pouvez utiliser SQL Gestion des Objets pour effectuer cette. Ce sont les mêmes objets que la Gestion de Studio utilise pour exécuter des requêtes. Je crois que Serveur.ConnectionContext.ExecuteNonQuery() va effectuer ce dont vous avez besoin.

6voto

John Points 1446

Le "GO" lot séparateur de mot-clé est utilisé par SQL Management Studio lui-même, de sorte qu'il sait où pour mettre fin à l'lots, il envoie au serveur, et il n'est pas transmis à SQL server. Vous pouvez même changer le mot clé dans Management Studio, si vous le désirez.

2voto

jason saldo Points 5036

Si vous ne voulez pas aller à la SMO route, vous pouvez rechercher et remplacer "GO" pour le ";" et la requête que vous le feriez. Notez que soly le dernier résultat sera retourné.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X