2012-01-13 37 views
7

Tôi có tập lệnh mysql trong một tệp mà tôi cần để có thể thực thi từ ứng dụng C# của tôi. Dưới đây là ví dụ về những gì tập lệnh chứa:Cách thực thi tệp * .sql mysql trong ứng dụng 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 ; 

Như bạn có thể thấy nó có một hỗn hợp các dòng gọi thủ tục lưu trữ và một số lệnh thả và tạo để cập nhật các thủ tục được lưu trữ khác.

Tôi đã thử hai phương pháp khác nhau để thực thi kịch bản và cả hai đã thất bại:

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

này ném ngoại lệ: Index lại vượt ra ngoài giới hạn của mảng.

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

Điều này ném ngoại lệ là có lỗi trong cú pháp sql của tôi.

Khi tôi chạy toàn bộ tập lệnh theo cách thủ công trong dbForge Studio, nó thực thi hoàn hảo. Làm thế nào tôi có thể nhận được tập lệnh này để thực thi chính xác từ ứng dụng C#

+0

Tập lệnh này có thay đổi không? Nếu vậy, có lẽ tốt nhất là bạn nên chạy chương trình 'mysql' ở dòng lệnh với kịch bản làm tham số. Nếu không, hãy tiêu thụ từng bước trong tập lệnh vào chương trình của bạn; theo cách đó, chuỗi ít giòn hơn, tức là bạn sẽ hoàn toàn dựa vào quy trình của riêng bạn chứ không phải một số tập lệnh có thể có hoặc không có ở đó và có thể có hoặc không hoạt động. –

+0

tiếc là tôi không thể sử dụng exe mysql để thực thi kịch bản vì máy chủ mysql có thể nằm trên một máy khác nhau – Brian

Trả lời

8

Hãy xem here. Bạn nên chỉ định một dấu phân tách cho MySqlScript (vì bạn đã lưu trữ thủ tục trong đó). Và truy vấn của bạn sẽ giống như thế:

-- 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 
$$ 

và sau đó mã của bạn:

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

Thật không may điều này vẫn còn ném ngoại lệ: Chỉ số nằm ngoài giới hạn của mảng. – Brian

+0

Bạn có thể thử mà không chỉ định DELIMITER $$ và USE (tên cơ sở dữ liệu của bạn đã có trong chuỗi kết nối) hay không. Hãy xem câu trả lời đã sửa đổi của tôi. (Tôi cũng đã sử dụng sai dấu phân cách đó là ví dụ mã của tôi (##), nó đã được sửa ngay bây giờ ($$) –

+0

Và ngoài ra, hãy kiểm tra mã ví dụ tại đây: http://dev.mysql.com/doc/refman/5.5/ vi/connector-net-tutorials-mysqlscript.html # connector-net-tutorials-mysqlscript-delimiter Bạn có thể thử sửa đổi mã của bạn để chỉ bao gồm định nghĩa thủ tục. Nó có thể xảy ra mà các thủ tục lưu trữ của bạn gọi (ở đầu tập lệnh) –

1

Bạn có thể chạy một Quy trình riêng để thực thi tập lệnh. Ví dụ:

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

Có thể bạn sẽ cần phải chơi với nó một chút tùy thuộc vào môi trường của bạn để bao gồm đường dẫn đến tập lệnh mysql hoặc tập lệnh sql.

+2

Vấn đề với điều này là máy chủ mySql có thể không nằm trên cùng một máy như ứng dụng C# – Brian

0

Tôi không chắc chắn cú pháp MySql gốc là gì, nhưng khi chúng tôi thực hiện chức năng tương tự cho Sql Server, chúng tôi phải chia tệp sql thành các khối dựa trên các giá trị bằng chữ (GO). thực thi (Sql Server Management Console).

Tôi nghi ngờ có thể có thông tin tương tự được nhúng trong yêu cầu của bạn ở trên, chẳng hạn như tuyên bố DEFINE.

Biết chính xác những gì MySql phàn nàn sẽ giúp tinh chỉnh giải pháp.

+0

Đó cũng là suy nghĩ của tôi . GO hoặc tương đương của nó không phải là SQL và trình phân tích cú pháp phân tích cú pháp sql trên đó.Ripping chúng ra hoặc sử dụng chúng để chia một kịch bản dài là cách chúng tôi đi là tốt. –

1

Làm thế nào nếu bạn đặt script sql của bạn trong một thủ tục lưu trữ? Nếu bạn vẫn muốn sử dụng cách này, hãy đính kèm tệp sql vào ứng dụng dưới dạng tệp tới tài nguyên ứng dụng (tệp .resx) và thực thi như sau:

MySql.Data.MySqlClient.MySqlCommand cmdMySQL = newMySqlConnection.CreateCommand(); 
cmdMySQL.CommandText = (System.String)globalResource.your_file_name; 
Các vấn đề liên quan