Consulta parametrizada donde el parámetro necesita ser modificado mySQL

asp.net c# dapper mysql sql

Pregunta

Estoy intentando construir migas de pan a partir de una tabla de autorreferencia. La consulta funciona perfectamente bien en MySQL Workbench, pero cuando se ejecuta en la aplicación, la consulta falla con

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

He buscado la sintaxis correcta para la versión de mi servidor (Percona Server (GPL), Release rel30.2, Revision 38.2). Estoy alojando el DB fuera de GoDaddy. La consulta es la siguiente:

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
        });

Donde Query(query es un método de envoltura para dapper que usa una cadena de conexión almacenada en las aplicaciones del sitio web).

¿Qué estoy haciendo mal? ¿Hay alguna forma de que pueda hacerlo mejor?

Respuesta aceptada

Utilice nombres distintos para los parámetros de Dapper y las variables de usuario de MySQL

Está utilizando la misma sintaxis para sus parámetros @l y @r y sus variables de usuario MySQL @l y @r . Dapper probablemente resuelva las variables en todos los casos, lo que provoca afirmaciones sin sentido como ...

  • 0 := 0 + 1 as lvl para @l
  • childId := Parent para @r

... y por lo tanto la MySQLException.

Para solucionar esto, simplemente cambie el nombre de su variable de usuario MySQL a algún valor que no coincida con ninguno de sus parámetros Dapper en esta consulta.

Pude reproducir esta MySQLException en mi entorno local y verifico que el cambio de la variable de usuario resuelve el problema.

Para reproducir MySQLException : nombre ambos @l .

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

Para generar un buen resultado : simplemente cambie el nombre de @l a algo como @test .

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

Haga esto tanto para @l como para @r , los parámetros @l y las variables de usuario necesitan nombres distintos.

Establecer Allow User Variables=True en la Cadena de Conexión MySQL

Incluir Allow User Variables=True en la cadena de Conexión de MySQL que está utilizando con el conector de MySQL. Después de resolver los problemas de nomenclatura, verifique esto si ve un error que indique que la variable de usuario MySQL necesita ser definida. Esto es falso de manera predeterminada y las variables de usuario no funcionarán en su consulta a menos que esto sea cierto.

Otras lecturas



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué