【问题标题】:MySQL .Net Connector Issue Executing RoutineMySQL .Net 连接器问题执行例程
【发布时间】:2014-01-31 15:38:20
【问题描述】:

我在让我的代码执行 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);

更新

一旦我启动一个没有. 的例程,验证这确实可以正常工作。

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

【问题讨论】:

  • 您是否尝试过从 C# 字符串中删除反引号?
  • 然后我会尝试将程序重命名为没有 Get 的东西。字首。似乎 Get 被错误地解释为数据库名称
  • 这是不可能的,因为程序正在 PHP 站点的生产环境中使用
  • 好吧,但至少应该尝试检查以排除这种可能性。但是,您是否安装了最新版本的 MySql 连接器?
  • 是的,实际上只是安装了它:)。我有一个为 MS SQL 构建的包装器类,并且因为我最近一直在做很多 MySQL 的东西,所以我想将它合并到一个单独的 MySQL 包装器中:) 我会看看我是否有访问权限来创建一个测试它的新程序

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


【解决方案1】:

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

但是,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 打开一个错误来修复提供程序(假设还没有一个已经打开)
2) 将存储过程的名称更改为不使用 .
3) 下载提供程序的代码,修复它,重新编译
4) 寻找另一个连接器

【讨论】:

  • 5) 将其称为 Text 类型并使用 Call Get.ShortenedURLs (?ID) 也可以...但我确信它的效率不如使用 StoredProcedure 作为我的命令类型。跨度>
  • 虽然...我也可以做#3 :)。感谢您对此的解释
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-03
  • 1970-01-01
相关资源
最近更新 更多