151 votes

Comment exécuter un fichier .SQL script en utilisant c#

Je suis sûr que cette question a déjà reçu une réponse, mais je n'ai pas trouvé de réponse en utilisant l'outil de recherche.

En utilisant C#, je voudrais exécuter un fichier .sql. Ce fichier contient plusieurs instructions sql, dont certaines sont réparties sur plusieurs lignes. J'ai essayé de lire le fichier et d'exécuter le fichier à l'aide d'ODP.NET ... mais je ne pense pas que ExecuteNonQuery soit vraiment conçu pour cela.

J'ai donc essayé d'utiliser sqlplus en créant un processus ... mais à moins que je ne crée le processus avec UseShellExecute réglé sur true, sqlplus se bloque et ne sort jamais. Voici le code qui ne fonctionne pas.

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "sqlplus";
p.StartInfo.Arguments = string.Format("xx/xx@{0} @{1}", in_database, s);
p.StartInfo.CreateNoWindow = true;

bool started = p.Start();
p.WaitForExit();

WaitForExit ne renvoie jamais .... Sauf si je règle UseShellExecute sur true. Un effet secondaire de UseShellExecute est que vous ne pouvez pas capturer la sortie redirigée.

9 votes

Bonjour M. Rich, votre question concernait Oracle et vous avez accepté une solution qui était pour sql server ? Vous avez changé votre DB pour sql server ?

207voto

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
using System.IO;
using System.Data.SqlClient;

public partial class ExcuteScript : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string sqlConnectionString = @"Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=ccwebgrity;Data Source=SURAJIT\SQLEXPRESS";

        string script = File.ReadAllText(@"E:\Project Docs\MX462-PD\MX756_ModMappings1.sql");

        SqlConnection conn = new SqlConnection(sqlConnectionString);

        Server server = new Server(new ServerConnection(conn));

        server.ConnectionContext.ExecuteNonQuery(script);
    }
}

5 votes

Super ! Cette solution a fonctionné pour moi pour pouvoir déposer et recréer une base de données, et ajouter des tables (via le fichier SQL script référencé).

11 votes

Cette méthode ne permet pas d'utiliser la commande "GO" dans votre script qui est autorisée lorsque vous exécutez un script depuis SQL Management Studio ou la commande osql. msdn.microsoft.com/fr/us/library/ms188037.aspx

20 votes

Rn222 : Je pense que vous avez confondu les méthodes ExecuteNonQuery, SqlCommand.ExecuteNonQuery ne permet pas d'utiliser les commandes "GO", mais Server.ConnectionContext.ExecuteNonQuery le fait définitivement (je l'utilise en ce moment même).

117voto

Hacko Points 431

J'ai essayé cette solution avec Microsoft.SqlServer.Management mais elle ne fonctionnait pas bien avec .NET 4.0. J'ai donc écrit une autre solution en utilisant uniquement le cadre de librairies .NET.

string script = File.ReadAllText(@"E:\someSqlScript.sql");

// split script on GO command
IEnumerable<string> commandStrings = Regex.Split(script, @"^\s*GO\s*$", RegexOptions.Multiline | RegexOptions.IgnoreCase);

Connection.Open();
foreach (string commandString in commandStrings)
{
    if (!string.IsNullOrWhiteSpace(commandString.Trim()))
    {
        using(var command = new SqlCommand(commandString, Connection))
        {
            command.ExecuteNonQuery();
        }
    }
}     
Connection.Close();

0 votes

Exactement. Cette solution ne ferme même pas le fichier après l'avoir utilisé. Cela pourrait être critique.

1 votes

Utilisez "RegexOptions.Multiline | RegexOptions.IgnoreCase" pour faire correspondre les cas "Go" ou "go" également.

1 votes

Je pense que l'indicateur RegexOptions.CultureInvariant devrait également être utilisé.

20voto

Xtian11 Points 93

Fonctionne sur Framework 4.0 ou supérieur. Supporte "GO". Affiche également le message d'erreur, la ligne et la commande sql.

using System.Data.SqlClient;

        private bool runSqlScriptFile(string pathStoreProceduresFile, string connectionString)
    {
        try
        {
            string script = File.ReadAllText(pathStoreProceduresFile);

            // split script on GO command
            System.Collections.Generic.IEnumerable<string> commandStrings = Regex.Split(script, @"^\s*GO\s*$",
                                     RegexOptions.Multiline | RegexOptions.IgnoreCase);
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                foreach (string commandString in commandStrings)
                {
                    if (commandString.Trim() != "")
                    {
                        using (var command = new SqlCommand(commandString, connection))
                        {
                        try
                        {
                            command.ExecuteNonQuery();
                        }
                        catch (SqlException ex)
                        {
                            string spError = commandString.Length > 100 ? commandString.Substring(0, 100) + " ...\n..." : commandString;
                            MessageBox.Show(string.Format("Please check the SqlServer script.\nFile: {0} \nLine: {1} \nError: {2} \nSQL Command: \n{3}", pathStoreProceduresFile, ex.LineNumber, ex.Message, spError), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return false;
                        }
                    }
                    }
                }
                connection.Close();
            }
        return true;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return false;
        }
    }

4 votes

Beau code, une chose très mineure est qu'il n'y a pas besoin de connection.Close() la connexion sera fermée par le using dans lequel vous l'avez emballé.

8voto

Binoj Antony Points 7519

Mettez la commande pour exécuter le sql script dans un fichier batch puis exécutez le code suivant

string batchFileName = @"c:\batosql.bat";
string sqlFileName = @"c:\MySqlScripts.sql";
Process proc = new Process();
proc.StartInfo.FileName = batchFileName;
proc.StartInfo.Arguments = sqlFileName;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.ErrorDialog = false;
proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(batchFileName);
proc.Start();
proc.WaitForExit();
if ( proc.ExitCode!= 0 )

dans le fichier batch, écrivez quelque chose comme ceci (exemple pour sql server)

osql -E -i %1

7voto

Neelam saini Points 61

Cela fonctionne pour moi :

public void updatedatabase()
{

    SqlConnection conn = new SqlConnection("Data Source=" + txtserver.Text.Trim() + ";Initial Catalog=" + txtdatabase.Text.Trim() + ";User ID=" + txtuserid.Text.Trim() + ";Password=" + txtpwd.Text.Trim() + "");
    try
    {

        conn.Open();

        string script = File.ReadAllText(Server.MapPath("~/Script/DatingDemo.sql"));

        // split script on GO command
        IEnumerable<string> commandStrings = Regex.Split(script, @"^\s*GO\s*$", RegexOptions.Multiline | RegexOptions.IgnoreCase);
        foreach (string commandString in commandStrings)
        {
            if (commandString.Trim() != "")
            {
                new SqlCommand(commandString, conn).ExecuteNonQuery();
            }
        }
        lblmsg.Text = "Database updated successfully.";

    }
    catch (SqlException er)
    {
        lblmsg.Text = er.Message;
        lblmsg.ForeColor = Color.Red;
    }
    finally
    {
        conn.Close();
    }
}

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