leer - execute script c# sql
Cómo ejecutar un archivo de script.SQL usando c# (8)
Coloque el comando para ejecutar la secuencia de comandos sql en un archivo por lotes y luego ejecute el siguiente código
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 )
en el archivo por lotes, escriba algo como esto (muestra para el servidor sql)
osql -E -i %1
Estoy seguro de que esta pregunta ya fue respondida, sin embargo, no pude encontrar una respuesta utilizando la herramienta de búsqueda.
Usando c # Me gustaría ejecutar un archivo .sql. El archivo sql contiene varias sentencias SQL, algunas de las cuales se dividen en varias líneas. Intenté leer el archivo e intenté ejecutar el archivo usando ODP.NET ... sin embargo, no creo que ExecuteNonQuery esté realmente diseñado para hacer esto.
Así que traté de usar sqlplus al generar un proceso ... sin embargo, a menos que genere el proceso con UseShellExecute establecido en verdadero, sqlplus se bloqueará y nunca saldrá. Aquí está el código que NO FUNCIONA.
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 nunca vuelve ... A menos que establezca UseShellExecute en verdadero. Un efecto secundario de UseShellExecute es que no puede capturar el resultado redirigido.
Esto funciona en Framework 4.0 o superior. Admite "IR". También muestre el mensaje de error, la línea y el comando 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;
}
}
Esto funciona para mí:
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();
}
}
Hay dos puntos para considerar.
1) Este código fuente funcionó para mí:
private static string Execute(string credentials, string scriptDir, string scriptFilename)
{
Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.WorkingDirectory = scriptDir;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.FileName = "sqlplus";
process.StartInfo.Arguments = string.Format("{0} @{1}", credentials, scriptFilename);
process.StartInfo.CreateNoWindow = true;
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return output;
}
Establecí el directorio de trabajo en el directorio de scripts, de modo que los scripts secundarios dentro del script también funcionen.
Llámalo, por ejemplo, como Execute("usr/pwd@service", "c:/myscripts", "script.sql")
2) Debe finalizar su script SQL con la instrucción EXIT;
Intenté esta solución con Microsoft.SqlServer.Management pero no funcionó bien con .NET 4.0, así que escribí otra solución usando .NET libs framework solamente.
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 (commandString.Trim() != "")
{
using(var command = new SqlCommand(commandString, Connection))
{
command.ExecuteNonQuery();
}
}
}
Connection.Close();
Logré encontrar la respuesta leyendo el manual :)
Este extracto de MSDN
El ejemplo de código evita una condición de interbloqueo llamando a p.StandardOutput.ReadToEnd antes de p.WaitForExit. Se puede producir una condición de interbloqueo si el proceso primario llama a p.WaitForExit antes de p.StandardOutput.ReadToEnd y el proceso secundario escribe suficiente texto para completar la secuencia redirigida. El proceso principal esperaría indefinidamente para que el proceso secundario salga. El proceso secundario esperaría indefinidamente para que el padre lea de la transmisión StandardOutput completa.
Hay un problema similar cuando lee todo el texto tanto de la salida estándar como de las secuencias de error estándar. Por ejemplo, el siguiente código C # realiza una operación de lectura en ambas transmisiones.
Convierte el código en esto;
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "sqlplus";
p.StartInfo.Arguments = string.Format("xxx/xxx@{0} @{1}", in_database, s);
bool started = p.Start();
// important ... read stream input before waiting for exit.
// this avoids deadlock.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
if (p.ExitCode != 0)
{
Console.WriteLine( string.Format("*** Failed : {0} - {1}",s,p.ExitCode));
break;
}
Que ahora sale correctamente
Se agregaron mejoras adicionales a la respuesta de surajits:
using System;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
using System.IO;
using System.Data.SqlClient;
namespace MyNamespace
{
public partial class RunSqlScript : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var connectionString = @"your-connection-string";
var pathToScriptFile = Server.MapPath("~/sql-scripts/") + "sql-script.sql";
var sqlScript = File.ReadAllText(pathToScriptFile);
using (var connection = new SqlConnection(connectionString))
{
var server = new Server(new ServerConnection(connection));
server.ConnectionContext.ExecuteNonQuery(sqlScript);
}
}
}
}
Además, tuve que agregar las siguientes referencias a mi proyecto:
-
C:/Program Files/Microsoft SQL Server/120/SDK/Assemblies/Microsoft.SqlServer.ConnectionInfo.dll
-
C:/Program Files/Microsoft SQL Server/120/SDK/Assemblies/Microsoft.SqlServer.Smo.dll
No tengo idea si esos son los dll: s adecuados para usar, ya que hay varias carpetas en C: / Program Files / Microsoft SQL Server pero en mi aplicación estos dos funcionan.
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);
}
}