【问题标题】:Query works fine via GUI, but returns generic error when try to run through Dapper查询通过 GUI 工作正常,但在尝试通过 Dapper 运行时返回一般错误
【发布时间】:2019-03-12 07:55:02
【问题描述】:

我有一个通过 GUI 在 MariaDB 服务器上运行良好的查询,但是一旦我尝试通过 Dapper C# 运行我就会收到错误:

MySql.Data.MySqlClient.MySqlException: '你的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以了解在 'DELIMITER $ 附近使用的正确语法 开始不是原子的

如果 (@EndDate

我正在使用常规 IDbConnection 即

using (IDbConnection con = new MySqlConnection(SQLConfig.UI))

并调用查询:

return con.Query<MembershipDynamic.MembershipStatus>(sqlQuery, new{ @MembershipId = membershipId}).Single();

相同的查询使用相同的membershipId 效果很好。

我不知道为什么不能通过 Dapper 运行完全相同的查询。

我的连接字符串是普通的,只有一个额外的参数

AllowUserVariables=True

由于查询不是问题,因为其他任何东西都可以正常运行,我猜想连接字符串丢失了一些东西???

我也试过设置

 public MembershipsRepo()
    {
        DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.MySqlDialect();
    }

这里是查询。我在直接实现 MySqlConnection 时尝试不使用 DELIMITER,但它只会返回第一次选择的结果(???)忽略其余部分...... SQL 是修改后的 MS SQL 过程。

SET @TypeId = NULL;
SET @StartDate = NULL;
SET @EndDate = NULL;
SET @GroupId = NULL;
SET @Status = NULL;

SELECT @TypeId := TypeId, @StartDate := StartDate, @EndDate := EndDate
FROM Membership_Memberships
WHERE MembershipId = @MembershipId;

DELIMITER $
BEGIN NOT ATOMIC

IF (@EndDate < NOW()) THEN
SET @GroupId = 3;
SET @STATUS = 'Expired';
END IF;

IF (SELECT COUNT(Id) FROM Membership_Trials WHERE MembershipId = 
@MembershipId AND Active = 1 ) > 0  THEN
SET @GroupId = 4;
SET @Status = 'Trial';

ELSE
SELECT @GroupId := T.GroupType, @Status := T.Name FROM Membership_Types T 
WHERE T.Id = @TypeId;
-- RETURN  Select @GroupId, @Status;
END IF;

END $
DELIMITER ;

SELECT @GroupId, @Status;

Dapper / ADO.NET 可以很好地处理简单的查询,但会失败一些更高级的查询:/

***** 编辑

经过一番调查,似乎 MySQL 被限制为每个请求 1 个查询,因此几乎不可能编写更高级的查询:/(使用变量,因为这些是由 Select 设置的)。

唯一的方法是创建我不会创建的过程,或者返回 Microsoft SQL 或使用其他 SQL...

这将是一个巨大的打击,因为我已经投入了将近 6 个月的时间来从 SQL 迁移到 MySQL:/(架构、复制等)

:((((((((((()))

【问题讨论】:

  • 我可以看看sqlQuery 的价值是什么或它来自哪里?另外:请注意,并非所有在 GUI 工具中工作的东西都是查询。例如,在 SQL Server(纯粹出于我的熟悉的示例)中,人们通常认为 GO 是 SQL 语法的一部分——它不是:GUI(SSMS)/命令行工具本身检测这些标记并使用它-实际上并没有发送它们。如果在 SqlConnection 上的 ADO.NET 查询中使用 GO:它将失败。所以我想知道DELIMETER $ BEGIN NOT ATOMIC(来自问题)是否类似。
  • BEGIN NOT ATOMIC 是在 MySQL 中运行 IF 语句所必需的。我认为 Dapper 不能正确处理更大和更高级的查询(它存储在 MS SQL 上的过程,但我想放弃所有存储的过程)。我在四处阅读,看起来 Dapper 从一开始就不是为此而设计的……我想我可能只是创建自定义 MySQL 连接器,用于更高级的查询。查询目前是基于 MySQL 文档编写的。
  • dapper 不关心(很多)你的查询是什么 - 它对它几乎没有兴趣 - 它可以是小,大,简单,复杂:不是 dapper 的问题.关心这一点的是 ADO.NET / MySqlClient 层。那么:您的查询在 ADO.NET 中有效吗?如果不是:它将无法通过 dapper 工作,因为 dapper 的工作是揭开 ADO.NET API 的神秘面纱,并围绕它提供实用功能。但是实际查询被传递到 ADO.NET/MySqlClient。
  • 我尝试删除定界/原子,但结果为 0 / null,即使变量在返回选择之前设置为特定值。
  • "我尝试删除定界/原子,但结果为 0 / null,即使变量在返回选择之前设置为特定值。"由于您尚未显示您的查询,因此很难对此发表评论

标签: c# mysql mariadb dapper


【解决方案1】:

好吧,看起来我们已经失去了几个月的工作。

MySQL 不是微软 SQL 的替代品。

基本上存储过程将返回所有选择(并加入/处理所有案例等。它必须做很多选择/加入/如果)。

不幸的是,这会破坏交易,因为它会导致返回 100 MB 的不必要数据并破坏整个平台。 (目前在 Microsoft SQL 上运行)

【讨论】:

    猜你喜欢
    • 2020-01-31
    • 2012-04-10
    • 2017-08-16
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多