You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL存储过程在Workbench正常运行但C#代码调用报错求助

解决C#调用MySQL存储过程创建语句时的DELIMITER语法错误问题

我之前也踩过一模一样的坑!你这段存储过程创建语句在Workbench里能正常跑,但C#调用就报错,核心原因其实很简单:DELIMITER是MySQL客户端工具(比如Workbench、命令行)专属的命令,MySQL服务器根本不认识它。

你收到的报错信息也直接点明了问题:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER $$ CREATE DEFINER=root@% PROCEDURE `AccountGetAccountOpeningClosi' at line 1

为什么Workbench能正常执行?

Workbench这类客户端会先解析DELIMITER命令,临时把SQL语句的结束符改成$$,这样存储过程里的分号就不会被当成整个语句的结束信号;等存储过程定义完成后,再把结束符改回;。但C#的MySqlCommand是直接把整个字符串发给服务器的,服务器看到DELIMITER就懵了——这根本不是合法的SQL指令啊!

怎么解决?

方案1:简化语句拆分执行(完全适配你的场景)

你的存储过程体里只有一条SELECT语句,没有嵌套的分号需要转义,所以完全可以删掉DELIMITER相关内容,把DROP和CREATE拆成两个独立命令执行:

修改后的SQL脚本:

DROP PROCEDURE IF EXISTS AccountGetAccountOpeningClosingStock;
CREATE DEFINER=`root`@`%` PROCEDURE `AccountGetAccountOpeningClosingStock`(IN _endDate datetime)
BEGIN
    Select * From openingclosingstock Where CreateDate <= _endDate order by CreateDate asc;
END;

对应的C#代码调整(记得用using自动释放资源,避免内存泄漏):

string myConnectionString = FetchDbConnectionString(environment, item);
using (MySqlConnection mySqlConnection = new MySqlConnection(myConnectionString))
{
    await mySqlConnection.OpenAsync();
    
    // 先执行删除存储过程的命令
    using (MySqlCommand dropCmd = new MySqlCommand("DROP PROCEDURE IF EXISTS AccountGetAccountOpeningClosingStock;", mySqlConnection))
    {
        await dropCmd.ExecuteNonQueryAsync();
    }
    
    // 再执行创建存储过程的命令
    string createProcSql = @"CREATE DEFINER=`root`@`%` PROCEDURE `AccountGetAccountOpeningClosingStock`(IN _endDate datetime)
                            BEGIN
                                Select * From openingclosingstock Where CreateDate <= _endDate order by CreateDate asc;
                            END;";
    using (MySqlCommand createCmd = new MySqlCommand(createProcSql, mySqlConnection))
    {
        await createCmd.ExecuteNonQueryAsync();
    }
}

方案2:用MySqlScript处理复杂存储过程(未来扩展用)

如果以后你的存储过程里需要写多个带分号的语句(比如多段SELECT、INSERT逻辑),可以用MySqlScript类(需要确保项目使用的是MySqlConnector库),它会模拟Workbench的DELIMITER解析逻辑:

string myConnectionString = FetchDbConnectionString(environment, item);
using (MySqlConnection mySqlConnection = new MySqlConnection(myConnectionString))
{
    await mySqlConnection.OpenAsync();
    
    string fullScript = @"DROP PROCEDURE IF EXISTS AccountGetAccountOpeningClosingStock;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `AccountGetAccountOpeningClosingStock`(IN _endDate datetime)
BEGIN
    Select * From openingclosingstock Where CreateDate <= _endDate order by CreateDate asc;
    -- 这里可以添加更多带分号的业务语句
END$$
DELIMITER ;";
    
    MySqlScript script = new MySqlScript(mySqlConnection, fullScript);
    await script.ExecuteAsync();
}

小提醒

  • 尽量使用最新版的MySqlConnector替代旧的MySql.Data库,兼容性和稳定性会更好。
  • 始终用using包裹数据库连接和命令对象,避免资源泄漏问题。

内容的提问来源于stack exchange,提问作者Partha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:16:31