2012-01-13 21 views
7

Tengo un script mysql en un archivo que necesito poder ejecutar desde mi aplicación C#. Este es un ejemplo de lo que contiene la secuencia de comandos:Cómo ejecutar * .sql archivo mysql en mi aplicación C#

USE osae; 

-- Set DB version 
CALL osae_sp_object_property_set('SYSTEM', 'DB Version', '0.3.5', '', ''); 
CALL osae_sp_object_property_set('SYSTEM', 'Debug', 'FALSE', '', ''); 
CALL osae_sp_object_type_property_add ('Prune Logs','Boolean','TRUE','SYSTEM',0); 
CALL osae_sp_object_property_set ('SYSTEM','Prune Logs','TRUE','',''); 

DELIMITER $$ 

DROP PROCEDURE IF EXISTS osae_sp_object_event_script_update$$ 
CREATE DEFINER = 'root'@'localhost' 
PROCEDURE osae_sp_object_event_script_update(IN pobject varchar(200), IN pevent varchar(200), IN ptext text) 
BEGIN 
DECLARE vObjectCount INT; 
DECLARE vObjectID INT; 
DECLARE vObjectTypeID INT; 
DECLARE vEventCount INT; 
DECLARE vEventID INT; 
    SELECT COUNT(object_id) INTO vObjectCount FROM osae_object WHERE UPPER(object_name)=UPPER(pobject); 
    IF vObjectCount > 0 THEN 
       SELECT object_id,object_type_id INTO vObjectID,vObjectTypeID FROM osae_object WHERE UPPER(object_name)=UPPER(pobject); 
     SELECT COUNT(event_id) INTO vEventCount FROM osae_object_type_event WHERE object_type_id=vObjectTypeID AND (UPPER(event_name)=UPPER(pevent) OR UPPER(event_label)=UPPER(pevent)); 
     IF vEventCount = 1 THEN  
      SELECT event_id INTO vEventID FROM osae_object_type_event WHERE object_type_id=vObjectTypeID AND (UPPER(event_name)=UPPER(pevent) OR UPPER(event_label)=UPPER(pevent)); 
      UPDATE osae_object_event_script SET event_script=ptext WHERE object_id=vObjectID AND event_id=vEventID; 
     -- CALL osae_sp_debug_log_add(CONCAT('Updated ',vObjectID,' - ',vEventID,ptext),''); 
     END IF; 
    END IF; 
END 
$$ 

DELIMITER ; 

Como se puede ver que tiene una mezcla de líneas que llaman a procedimientos almacenados y alguna gota y CREATE para actualizar otros procedimientos almacenados.

me han tratado dos métodos diferentes para ejecutar la secuencia de comandos y ambos han fallado:

MySqlScript script = new MySqlScript(connection, File.ReadAllText("script.sql")); 
script.Execute(); 

Esto produce la excepción: Índice fuera de los límites de la matriz.

MySqlCommand upgCommand = new MySqlCommand(); 
upgCommand.Connection = connection; 
upgCommand.CommandText = File.ReadAllText("script.sql"); 
upgCommand.ExecuteNonQuery(); 

Esto arroja la excepción de que hay un error en mi sintaxis sql.

Cuando ejecuto todo el script manualmente en dbForge Studio, se ejecuta perfectamente. ¿Cómo puedo obtener este script para que se ejecute correctamente desde mi aplicación C#

+0

Será este guión jamás puede cambiar? Si es así, probablemente sea mejor que el programa ejecute 'mysql' en la línea de comando con el script como parámetro. De lo contrario, consuma cada paso del guión en su programa; de esa forma la cadena es menos frágil, es decir, dependerá completamente de su propio proceso y no de una secuencia de comandos que puede estar o no estar allí y que puede funcionar o no. –

+0

desafortunadamente no puedo usar el exe mysql para ejecutar el script porque el servidor mysql puede estar en un equipo diferente – Brian

Respuesta

8

Echa un vistazo a here. Debe especificar un delimitador para MySqlScript (ya que tiene el procedimiento almacenado allí). Y la consulta debe verse como:

-- Set DB version 
CALL osae_sp_object_property_set('SYSTEM', 'DB Version', '0.3.5', '', '')$$ 
CALL osae_sp_object_property_set('SYSTEM', 'Debug', 'FALSE', '', '')$$ 
CALL osae_sp_object_type_property_add ('Prune Logs','Boolean','TRUE','SYSTEM',0)$$ 
CALL osae_sp_object_property_set ('SYSTEM','Prune Logs','TRUE','','')$$ 



DROP PROCEDURE IF EXISTS osae_sp_object_event_script_update$$ 
CREATE DEFINER = 'root'@'localhost' 
PROCEDURE osae_sp_object_event_script_update(IN pobject varchar(200), IN pevent varchar(200), IN ptext text) 
BEGIN 
DECLARE vObjectCount INT; 
DECLARE vObjectID INT; 
DECLARE vObjectTypeID INT; 
DECLARE vEventCount INT; 
DECLARE vEventID INT; 
    SELECT COUNT(object_id) INTO vObjectCount FROM osae_object WHERE UPPER(object_name)=UPPER(pobject); 
    IF vObjectCount > 0 THEN 
       SELECT object_id,object_type_id INTO vObjectID,vObjectTypeID FROM osae_object WHERE UPPER(object_name)=UPPER(pobject); 
     SELECT COUNT(event_id) INTO vEventCount FROM osae_object_type_event WHERE object_type_id=vObjectTypeID AND (UPPER(event_name)=UPPER(pevent) OR UPPER(event_label)=UPPER(pevent)); 
     IF vEventCount = 1 THEN  
      SELECT event_id INTO vEventID FROM osae_object_type_event WHERE object_type_id=vObjectTypeID AND (UPPER(event_name)=UPPER(pevent) OR UPPER(event_label)=UPPER(pevent)); 
      UPDATE osae_object_event_script SET event_script=ptext WHERE object_id=vObjectID AND event_id=vEventID; 
     -- CALL osae_sp_debug_log_add(CONCAT('Updated ',vObjectID,' - ',vEventID,ptext),''); 
     END IF; 
    END IF; 
END 
$$ 

y entonces su código:

MySqlScript script = new MySqlScript(connection, File.ReadAllText("script.sql")); 
script.Delimiter = "$$"; 
script.Execute(); 
+0

Lamentablemente, esto todavía arroja la excepción: el índice estaba fuera de los límites de la matriz. – Brian

+0

Puede intentarlo sin especificar DELIMITER $$ y USE (su nombre de base de datos ya está en la cadena de conexión). Eche un vistazo a mi respuesta modificada. (También he usado el delimitador equivocado en mi ejemplo de código (##), ahora está arreglado ($$) –

+0

Y también, consulte el código de ejemplo aquí: http://dev.mysql.com/doc/refman/5.5/ es/connector-net-tutorials-mysqlscript.html # connector-net-tutorials-mysqlscript-delimiter Puede intentar modificando su código para incluir solo la definición de procedimiento. Puede suceder que sus procedimientos almacenados llamen (al comienzo del script) están causando problemas. –

1

Puede ejecutar un proceso separado para ejecutar el script. Por ejemplo:

Process.Start("mysql < script.sql"); 

Usted está probablemente va a tener que jugar con él un poco dependiendo de su entorno para incluir rutas de acceso al ejecutable mysql o la secuencia de comandos SQL.

+2

Problema con esto es que el servidor mySql puede no estar en la misma máquina que la aplicación C# – Brian

0

No estoy 100% seguro de cuál es la sintaxis MySql nativa, pero cuando realizamos funcionalidades similares para Sql Server, tenemos que dividir el archivo sql en fragmentos basados ​​en los valores literales (GO) que solo utiliza la consulta ejecutor (Sql Server Management Console).

Sospecho que puede haber información similar incrustada en su solicitud anterior, como la sentencia DEFINE.

Saber exactamente de qué se quejaba MySql ayudaría a refinar la solución.

+0

Esa fue mi idea también . GO o su equivalente no es SQL y el analizador sql se atasca en él.Tirarlos o usarlos para dividir un guión largo es la forma en que vamos también. –

1

Cómo si usted pone su secuencia de comandos SQL en un procedimiento almacenado? Si aún desea utilizar esta forma adjuntar el archivo sql para aplicación como archivo para los recursos de la aplicación (.resx) y ejecutarlo así:

MySql.Data.MySqlClient.MySqlCommand cmdMySQL = newMySqlConnection.CreateCommand(); 
cmdMySQL.CommandText = (System.String)globalResource.your_file_name; 
Cuestiones relacionadas