文档首页
MySQL Connector/NET 开发人员指南
相关文档 下载本手册
PDF (US Ltr) - 1.3Mb
PDF (A4) - 1.3Mb


MySQL Connector/NET 开发人员指南  /  Connector/NET 教程  /  教程:使用 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));

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

MySqlScript 对象将在使用 Connection 属性设置的连接上执行指定的脚本。同样,此属性可以被直接设置,也可以通过 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. Error - 如果发生错误,则生成。

  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.");
        }
    }
}