本教程将教你如何使用 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 类有几个与之相关的事件。有
Error - 如果发生错误,则生成。
ScriptCompleted - 脚本成功完成执行时生成。
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
的原因。
根据脚本的性质,你可能需要控制用于分隔构成脚本的语句的分隔符。最常见的示例是你的脚本中包含多语句存储例程。在这种情况下,如果使用默认分隔符 “;”,则在尝试执行脚本时会收到错误。例如,考虑以下存储例程
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.");
}
}
}