参数化查询需要修改参数mySQL

时间:2017-05-27 02:57:41

标签: c# mysql sql asp.net dapper

我正在尝试从自引用表中构建面包屑。该查询在MySQL Workbench中运行得非常好,但在应用程序中运行时,查询失败并带有

Unhandled Exception: MySql.Data.MySqlClient.MySqlException: 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 ':= Parent
                    FROM
                            Codebook
                    WHERE
                            id = _id
    ) as ParentId,
' at line 6

我已经为我的服务器版本寻找了正确的语法(Percona Server(GPL),Release rel30.2,Revision 38.2)。我正在托管GoDaddy的数据库。 查询如下:

var query = @"SELECT T2.* FROM (
SELECT
    @r as _id,
    (
        SELECT 
            @r := Parent
        FROM
            Codebook
        WHERE 
            id = _id
    ) as ParentId,
    @l := @l + 1 as lvl
FROM
    Codebook
WHERE
    @r <> 0
) T1
JOIN Codebook T2
ON T1._id = T2.Id
ORDER BY T1.lvl DESC";
        return Query(query, new
        {
            r = childId,
            l = 0
        });

其中Query(query是dapper的包装器方法,它使用存储在网站appsettings中的连接字符串。

我做错了什么?无论如何我可以做得更好吗?

1 个答案:

答案 0 :(得分:2)

为Dapper参数和MySQL用户变量使用不同的名称

您的dapper参数@l@r以及MySQL user variables @l@r的语法相同。 Dapper可能会在每种情况下解决变量,导致无意义的陈述,如......

    {li> 0 := 0 + 1 as lvl @l {li> childId := Parent @r

...因此MySQLException。

要解决此问题,只需将MySQL用户变量重命名为某个值,该值与此查询中的任何一个Dapper参数都不匹配。

我能够在本地环境中重现此MySQLException,并验证更改用户变量可以解决问题。

重现MySQLException :同时命名@l

    private int givenSameNames_ExpectMySQLException(IDbConnection conn)
    {
        return conn.Query<int>("SELECT @l := @l + 1", new
        {
            l = 1
        }).FirstOrDefault();
    }

要产生良好的结果:只需将@l重命名为@test

    private int givenDifferentNames_ExpectSuccess(IDbConnection conn)
    {
        return conn.Query<int>("SELECT @test := @l + 1", new
        {
            l = 1
        }).FirstOrDefault();
    } 

@l@r执行此操作 - dapper参数和用户变量需要不同的名称。

在MySQL连接字符串

中设置Allow User Variables=True

在您使用MySQL连接器的MySQL连接字符串中包含Allow User Variables=True。解决命名问题后,如果发现错误,请注意需要定义MySQL用户变量,请检查此问题。默认情况下这是错误的,用户变量在查询中不起作用,除非这是真的。

进一步阅读