即使连接已关闭,MySql也会执行MySqlScript

时间:2014-10-20 18:18:08

标签: c# mysql mysql-connector

即使连接已关闭,mysql是否可以执行脚本? 我正在使用mysql社区服务器,通过.NET连接器API。 使用c#测试API。

我有以下静态类

using System;
using System.Data;

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

public static class DataBase
{
    static string connStr = "server=localhost;user=root;port=3306;password=*******;";
    static MySqlConnection conn;

    public static bool Connect()
    {        
        conn = new MySqlConnection(connStr);   
        try
        {            
            conn.Open();            
        }
        catch (Exception Ex)
        {
            ErrorHandler(Ex);
            return false;
        }
        return true;
    }
    public static int ExecuteScript(string scripttext) // returns the number of statements executed
    {
        MySqlCommand cmd = conn.CreateCommand();
        cmd.CommandText = scripttext;
        MySqlScript script;
        int count= 0;

        try
        {
            script = new MySqlScript(conn, cmd.CommandText);

            script.Error += new MySqlScriptErrorEventHandler(script_Error);
            script.ScriptCompleted += new EventHandler(script_ScriptCompleted);
            script.StatementExecuted += new MySqlStatementExecutedEventHandler(script_StatementExecuted);
            count = script.Execute();
        }
        catch (Exception Ex)
        {
            count = -1;
            ErrorHandler(Ex);            
        }
        return count;
    }

    # region EventHandlers
    static void script_StatementExecuted(object sender, MySqlScriptEventArgs args)
    {
        string Message = "script_StatementExecuted";
    }

    static void script_ScriptCompleted(object sender, EventArgs e)
    {
       string Message = "script_ScriptCompleted!";
    }

    static void script_Error(Object sender, MySqlScriptErrorEventArgs args)
    {
        string Message = "script_Error: " + args.Exception.ToString();
    }
    # endregion
    public static bool Disconnect()
    {
        try
        {
            conn.Close();
        }
        catch (Exception Ex)
        {
            ErrorHandler(Ex);
            return false;
        }
        return true;
    }
    public static void ErrorHandler(Exception Ex)
    {
        Console.WriteLine(Ex.Source);
        Console.WriteLine(Ex.Message);
        Console.WriteLine(Ex.ToString());
    }

}

我正在使用以下代码来测试此类

using System;
using System.Data;
namespace Sample
{
    public class Sample
    {
        public static void Main()
        {
            if (DataBase.Connect() == true)
                Console.WriteLine("Connected");

            if (DataBase.Disconnect() == true)
                Console.WriteLine("Disconnected");

            int count = DataBase.ExecuteScript("drop database sample");
            if (count != -1)
            {
                Console.WriteLine(" Sample Script Executed");
                Console.WriteLine(count);
            }

            Console.ReadKey();

        }


    }
}

我注意到即使我已经使用Disconnect()关闭了我的MySql连接 - 我已经定义了,mysql继续执行我给下一个命令,并且没有生成错误。

我觉得我做错了,因为当我尝试在已关闭的连接上执行脚本时应该生成错误。

我的代码/逻辑中存在问题还是mysql连接器存在一些缺陷?

我确实通过mysql工作台检查了命令是否正确执行了。

1 个答案:

答案 0 :(得分:2)

这是MySqlScript.Execute代码的反编译....

public unsafe int Execute()
{

    ......

    flag = 0;
    if (this.connection != null)
    {
        goto Label_0015;
    }
    throw new InvalidOperationException(Resources.ConnectionNotSet);
Label_0015:
    if (this.query == null)
    {
        goto Label_002A;
    }
    if (this.query.Length != null)
    {
        goto Label_002C;
    }
Label_002A:
    return 0;
Label_002C:
    if (this.connection.State == 1)
    {
        goto Label_0047;
    }
    flag = 1;
    this.connection.Open();
    ....

正如您所看到的,当您构建MySqlScript时,传递的连接将保存在内部变量中,并且在执行脚本之前,如果内部连接变量已关闭,则代码会打开它。没有选中,但我想它在退出之前也会关闭连接(注意打开前标志= 1)

我建议更改代码以避免保留全局MySqlConnection对象。你没有任何收获,并且有很大的风险可能会产生非常困难的错误。

static string connStr = "server=localhost;user=root;port=3306;password=*******;";

public static MySqlConnection Connect()
{        
    MySqlConnection conn = new MySqlConnection(connStr);   
    conn.Open();            
    return conn;
}

此方法允许编写使用Using Statement

的代码
public static int ExecuteScript(string scripttext) // returns the number of statements executed
{
    using(MySqlConnection conn = Database.Connect())
    using(MySqlCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = scripttext;
        ....
    }
}

Using语句将关闭并处理连接和命令,释放宝贵的资源,如果发生异常,您将确保连接已关闭并处理