sql >> Base de Datos >  >> RDS >> Mysql

El selector JSON del generador de consultas de Laravel `field->key` provoca un error de sintaxis

No hay nada malo con tu consulta. Es tu entorno.

Problema

MySqlGrammar traduce el field->key notación en nombres de campo (en el lado de Laravel) en field->'$.key' extracciones de estilo (en el lado de MySQL):

/**
 * Wrap the given JSON selector.
 *
 * @param  string  $value
 * @return string
 */
protected function wrapJsonSelector($value)
{
    $path = explode('->', $value);

    $field = $this->wrapValue(array_shift($path));

    $path = collect($path)->map(function ($part) {
        return '"'.$part.'"';
    })->implode('.');

    // Here:
    return sprintf('%s->\'$.%s\'', $field, $path);
}

Acabo de confirmar que MariaDB no es compatible con -> operador de extracción como un alias para el JSON_EXTRACT() función. Sin embargo, la misma consulta funciona en un servidor MySQL 5.7 estándar.

Asumiendo esta prueba tabla:

╔════╤══════════════════╗
║ id │ payload          ║
╟────┼──────────────────╢
║  1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝

Una consulta que utiliza el -> operador de extracción:

SELECT payload->"$.b" FROM test;

falla contra MariaDB 10.2.8 mientras produce un 2 correcto contra un servidor MySQL 5.7.19.

Soluciones

La solución correcta depende de lo que esté usando en producción.

Reemplazar MariaDB

Si está utilizando MySQL, reemplace MariaDB con MySQL en su entorno de desarrollo. En una máquina macOS administrada por homebrew, sería tan fácil como:

brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql

sus datos permanecerán intactos.

Reescribe tus consultas

Sin embargo, si usa MariaDB en producción, debe volver a escribir sus consultas para usar JSON_EXTRACT() funciona como Elias ya mencionado . Como puede ver, debe ser mucho más detallado con la API de Laravel.

La consulta anterior sería:

SELECT JSON_EXTRACT(payload, "$.b") FROM test;