MySQL 连接器/NET 开发人员指南  / 第 6 章连接器/NET 教程  /  6.8 教程:使用 MySqlScript

6.8 教程:使用 MySqlScript

本教程教您如何使用 MySqlScript该类。此类使您能够执行一系列语句。根据具体情况,这可能比使用 MySqlCommand方法更方便。

MySqlScript可以在随 MySQL Connector/NET 提供的参考文档中找到该类 的更多详细信息。

要运行本教程中的示例程序,请使用mysql命令行客户端或 MySQL Workbench 设置一个简单的测试数据库和表。此处给出了mysql 命令行客户端的命令:

CREATE DATABASE TestDB;
USE TestDB;
CREATE TABLE TestTable (id INT NOT NULL PRIMARY KEY
  AUTO_INCREMENT, name VARCHAR(100));

类的主要方法MySqlScriptExecute方法。此方法导致执行分配给MySqlScript 对象的Query属性的脚本(语句序列) 。可以通过构造函数或使用 Query属性设置Query属性。 返回执行的语句数。 MySqlScriptExecute

该对象将使用Connection属性MySqlScript在连接集上执行指定的脚本 。同样,可以直接或通过 构造函数设置此属性。以下代码片段说明了这一点: MySqlScript

string sql = "SELECT * FROM TestTable";
...
MySqlScript script = new MySqlScript(conn, sql);
...
MySqlScript script = new MySqlScript();
script.Query = sql;
script.Connection = conn;
...
script.Execute();

MySqlScript 类有几个与之关联的事件。有:

  1. 错误 - 如果发生错误则生成。

  2. ScriptCompleted - 在脚本成功完成执行时生成。

  3. StatementExecuted - 在执行每个语句后生成。

可以为这些事件中的每一个分配事件处理程序。这些用户提供的例程在连接事件发生时被回调。以下代码显示了如何设置事件处理程序。

script.Error += new MySqlScriptErrorEventHandler(script_Error);
script.ScriptCompleted += new EventHandler(script_ScriptCompleted);
script.StatementExecuted += new MySqlStatementExecutedEventHandler(script_StatementExecuted);

在 VisualStudio 中,您可以通过使用制表符完成来填写存根例程来节省键入。例如,首先键入script.Error +=。然后按TAB键,然后再次按 TAB键。分配完成,并创建存根事件处理程序。一个完整的工作示例如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data;
using MySql.Data;
using MySql.Data.MySqlClient;

namespace MySqlScriptTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string connStr = "server=localhost;user=root;database=TestDB;port=3306;password=******";
            MySqlConnection conn = new MySqlConnection(connStr);

            try
            {
                Console.WriteLine("Connecting to MySQL...");
                conn.Open();

                string sql = "INSERT INTO TestTable(name) VALUES ('Superman');" +
                             "INSERT INTO TestTable(name) VALUES ('Batman');" +
                             "INSERT INTO TestTable(name) VALUES ('Wolverine');" +
                             "INSERT INTO TestTable(name) VALUES ('Storm');";

                MySqlScript script = new MySqlScript(conn, sql);
              
                script.Error += new MySqlScriptErrorEventHandler(script_Error);
                script.ScriptCompleted += new EventHandler(script_ScriptCompleted);
                script.StatementExecuted += new MySqlStatementExecutedEventHandler(script_StatementExecuted);
              
                int count = script.Execute();

                Console.WriteLine("Executed " + count + " statement(s).");
                Console.WriteLine("Delimiter: " + script.Delimiter);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            conn.Close();
            Console.WriteLine("Done.");
        }

        static void script_StatementExecuted(object sender, MySqlScriptEventArgs args)
        {
            Console.WriteLine("script_StatementExecuted");  
        }

        static void script_ScriptCompleted(object sender, EventArgs e)
        {
            /// EventArgs e will be EventArgs.Empty for this method
            Console.WriteLine("script_ScriptCompleted!");
        }

        static void script_Error(Object sender, MySqlScriptErrorEventArgs args)
        {
            Console.WriteLine("script_Error: " + args.Exception.ToString());
        }
    }
}

script_ScriptCompleted事件处理程序中,EventArgs参数 e将为EventArgs.Empty. 在ScriptCompleted事件的情况下,没有要获取的额外数据,这就是事件对象是 EventArgs.Empty.

在 MySqlScript 中使用定界符

根据脚本的性质,您可能需要控制用于分隔构成脚本的语句的定界符。最常见的示例是将多语句存储例程作为脚本的一部分。在这种情况下,如果默认分隔符; 时,您将在尝试执行脚本时收到错误消息。例如,考虑以下存储例程:

CREATE PROCEDURE test_routine()
BEGIN
    SELECT name FROM TestTable ORDER BY name;
    SELECT COUNT(name) FROM TestTable;
END

该例程实际上需要作为单个语句在 MySQL 服务器上执行。但是,使用默认分隔符 ; MySqlScript班级会将以上解释为两个陈述,第一个是:

CREATE PROCEDURE test_routine()
BEGIN
    SELECT name FROM TestTable ORDER BY name;

将此作为语句执行会产生错误。为了解决这个问题MySqlScript,支持设置不同的定界符。这是通过 Delimiter属性实现的。例如,您可以将分隔符设置为?? ,在这种情况下,上面存储的例程在执行时将不再产生错误。脚本中可以分隔多个语句,例如,您可以有一个三语句脚本,例如:

string sql = "DROP PROCEDURE IF EXISTS test_routine??" +
             "CREATE PROCEDURE test_routine() " +
             "BEGIN " +
             "SELECT name FROM TestTable ORDER BY name;" +
             "SELECT COUNT(name) FROM TestTable;" +
             "END??" +
             "CALL test_routine()";

您可以通过设置Delimiter属性 随时更改分隔 符。以下代码显示了一个完整的工作示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using MySql.Data;
using MySql.Data.MySqlClient;

namespace ConsoleApplication8
{
    class Program
    {
        static void Main(string[] args)
        {
            string connStr = "server=localhost;user=root;database=TestDB;port=3306;password=******";
            MySqlConnection conn = new MySqlConnection(connStr);

            try
            {
                Console.WriteLine("Connecting to MySQL...");
                conn.Open();

                string sql =    "DROP PROCEDURE IF EXISTS test_routine??" +
                                "CREATE PROCEDURE test_routine() " +
                                "BEGIN " +
                                "SELECT name FROM TestTable ORDER BY name;" +
                                "SELECT COUNT(name) FROM TestTable;" +
                                "END??" +
                                "CALL test_routine()";

                MySqlScript script = new MySqlScript(conn);
          
                script.Query = sql;
                script.Delimiter = "??";
                int count = script.Execute();
                Console.WriteLine("Executed " + count + " statement(s)");
                script.Delimiter = ";";
                Console.WriteLine("Delimiter: " + script.Delimiter);
                Console.WriteLine("Query: " + script.Query);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            conn.Close();
            Console.WriteLine("Done.");
        }
    }
}