MySQL .Net连接器问题执行例程

时间:2014-01-31 15:38:21

标签: c# mysql .net c#-4.0 .net-4.0

我在执行MySQL例程时遇到问题。

保持弹出错误:

Procedure or function 'ShortenedURLS' cannot be found in database 'Get'.

例程

DELIMITER $$

USE `o7thurlshortner`$$

DROP PROCEDURE IF EXISTS `Get.ShortenedURLS`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `Get.ShortenedURLS`(IN `ID` BIGINT)
    NO SQL
SELECT `ShortID`, `ShortCode`, `URL`, `ClickThroughs`
FROM `Shortener`
WHERE `AccountID` = ID$$

DELIMITER ;

代码 - 访问和运行例程

    internal DbDataReader GetResults()
    {
        try
        {
            // check for parameters
            if (AreParams())
            {
                PrepareParams(_Cmd);
            }
            // set our connection
            _Cmd.Connection = _Conn;
            // set the type of query to run
            _Cmd.CommandType = _QT;
            // set the actual query to run
            _Cmd.CommandText = _Qry;
            // open the connection
            _Cmd.Connection.Open();
            // prepare the command with any parameters that may have gotten added
            _Cmd.Prepare();
            // Execute the SqlDataReader, and set the connection to close once returned
            _Rdr = _Cmd.ExecuteReader(CommandBehavior.CloseConnection);
            // clear out any parameters
            _Cmd.Parameters.Clear();
            // return our reader object
            return (!_Rdr.HasRows) ? null : _Rdr;
        }
        catch (DbException SqlEx)
        {
            _Msg += "Acccess.GetResults SqlException: " + SqlEx.Message;
            ErrorReporting.WriteEm.WriteItem(SqlEx, "o7th.Class.Library.Data.MySql.Access.GetResults", _Msg);
            return null;
        }
        catch (Exception ex)
        {
            _Msg += "Acccess.GetResults Exception: " + ex.Message;
            ErrorReporting.WriteEm.WriteItem(ex, "o7th.Class.Library.Data.MySql.Access.GetResults", _Msg);
            return null;
        }
    }

代码 - 将其关闭

        IList<Typing> _T = Wrapper.GetResults<Typing>("Get.ShortenedURLS",
            System.Data.CommandType.StoredProcedure,
            new string[] { "?ID" },
            new object[] { 1 },
            new MySqlDbType[] { MySqlDbType.Int32 },
            false);

更新

验证一旦我在没有.的情况下启动例程,它就能正常工作。

如果我的例程确实有.,我怎么能让它工作,我不能简单地重写与高流量网站绑定的生产数据库中的现有程序......

1 个答案:

答案 0 :(得分:2)

为了调用存储过程,你必须在反引号中包装它的名称,因为它包含特殊字符.

但是,mysql连接器代码中存在一个错误,导致它再次逃脱它。指定时

cmd.CommandType = CommandType.StoredProcedure;

执行阅读器中的代码分支,如下所示...

if (statement == null || !statement.IsPrepared)
{
  if (CommandType == CommandType.StoredProcedure)
    statement = new StoredProcedure(this, sql);
  else
    statement = new PreparableStatement(this, sql);
}

// stored procs are the only statement type that need do anything during resolve
statement.Resolve(false); // the problem occurs here

Resolve所做的部分是修复程序名称..

//StoredProcedure.cs line 104-112
private string FixProcedureName(string name)
{
    string[] parts = name.Split('.');
    for (int i = 0; i < parts.Length; i++)
        if (!parts[i].StartsWith("`", StringComparison.Ordinal))
            parts[i] = String.Format("`{0}`", parts[i]);
    if (parts.Length == 1) return parts[0];
    return String.Format("{0}.{1}", parts[0], parts[1]);
}

正如您在此处所见,只要存储过程名称具有。在其中,存储过程的名称被分解为多个部分并单独转义,这导致您的代码无法调用您的存储过程。

所以解决这个问题的唯一方法就是......

1)用oracle打开一个bug来修复提供者(假设没有一个已经打开)
2)将存储过程的名称更改为不使用。
3)下载提供商的代码,修复它,重新编译
4)找到另一个连接器