【问题标题】:How to use DELIMITER in mariadb using the .NET MySql connector?如何使用 .NET MySql 连接器在 mariadb 中使用 DELIMITER?
【发布时间】:2018-09-21 14:36:38
【问题描述】:

我正在使用 MariaDB 10.2.12 并使用 .NET MySQL 连接器进行连接。以下触发器在 MySQL Workbench 中工作正常:

DELIMITER //
CREATE TRIGGER update_last_modified
BEFORE UPDATE ON users
FOR EACH ROW
BEGIN
    DECLARE miscdataWithDate JSON;
    IF JSON_CONTAINS_PATH(NEW.miscdata, 'all', '$.v1.lastModified2') THEN
        SET NEW.miscdata = JSON_REPLACE(NEW.miscdata, '$.v1.lastModified2', UTC_TIMESTAMP());
    ELSE
        SET miscdataWithDate = JSON_SET('{"v1": {}}', '$.v1.lastModified2', UTC_TIMESTAMP());
        SET NEW.miscdata = JSON_MERGE(NEW.miscdata, miscdataWithDate);
    END IF;
END; //
DELIMITER ;

为了从 C#/.NET 运行命令,我使用了以下命令。我尝试了使用和不使用最后的分号,以防图书馆添加分号:

using (var cmd = new MySqlCommand(@"CREATE TRIGGER update_last_modified
    BEFORE INSERT ON users
    FOR EACH ROW
    BEGIN
        DECLARE miscdataWithDate JSON;
        IF JSON_CONTAINS_PATH(NEW.miscdata, 'all', '$.v1.lastModified') THEN
            SET NEW.miscdata = JSON_REPLACE(NEW.miscdata, '$.v1.lastModified', UTC_TIMESTAMP());
        ELSE
            SET miscdataWithDate = JSON_SET('{""v1"": {}}', '$.v1.lastModified', UTC_TIMESTAMP());
            SET NEW.miscdata = JSON_MERGE(NEW.miscdata, miscdataWithDate);
        END IF;
    END; //
    DELIMITER ;", connection))
{
    await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
}

当触发器被定义(未调用)时,错误是:

Unhandled Exception: System.AggregateException: One or more errors occurred. (You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '//
    DELIMITER' at line 1) ---> MySql.Data.MySqlClient.MySqlException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '//
    DELIMITER' at line 1

如果我简化查询使其不需要设置DELIMITER,它就可以工作。但即使是带有自定义分隔符的非常简单的触发器也会失败。

【问题讨论】:

    标签: mysql asp.net .net mariadb


    【解决方案1】:

    在搜索其他人如何从 .NET 中成功使用 MySQL/MariaDB 的分隔符时,我发现了以下文章:https://dev.mysql.com/doc/connector-net/en/connector-net-tutorials-mysqlscript-delimiter.html

    给出的示例使用MySqlScript 而不是MySqlCommand,所以我相信MySqlCommand 根本不支持分隔符。这是更新后的代码,效果很好:

    MySqlScript script = new MySqlScript(connection, @"CREATE TRIGGER update_last_modified
        BEFORE INSERT ON users
        FOR EACH ROW
        BEGIN
            DECLARE miscdataWithDate JSON;
            IF JSON_CONTAINS_PATH(NEW.miscdata, 'all', '$.v1.lastModified') THEN
                SET NEW.miscdata = JSON_REPLACE(NEW.miscdata, '$.v1.lastModified', UTC_TIMESTAMP());
            ELSE
                SET miscdataWithDate = JSON_SET('{""v1"": {}}', '$.v1.lastModified', UTC_TIMESTAMP());
                SET NEW.miscdata = JSON_MERGE(NEW.miscdata, miscdataWithDate);
            END IF;
        END; //");
    script.Delimiter = "//";
    await script.ExecuteAsync().ConfigureAwait(false);
    

    【讨论】:

    • 你不应该把//也去掉吗?
    • @RickJames 如果此脚本有多个语句,则在语句之间需要//。而且我相信分隔符在末尾是可选的,因此 IMO 将其保留在每个语句的末尾会更清楚。
    • 我不明白为什么你需要构造一个脚本而不是简单地执行SQ​​L,逐个语句。
    • @RickJames 你是对的。就我而言,这不是问题。但是,我想在某些情况下,逻辑是作为 .sql 文件提供的,并且不能轻易更改过程。肯定是一个边缘案例,但可能对某人很重要。此外,MySqlScript 允许更轻松地在代码和另一个调试环境之间进行转换,从而减少重新格式化导致的错误。
    猜你喜欢
    • 2021-11-06
    • 2014-08-17
    • 2021-09-12
    • 2021-08-30
    • 1970-01-01
    • 2022-01-11
    • 2016-09-20
    • 1970-01-01
    • 2021-07-10
    相关资源
    最近更新 更多