Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

O seletor JSON do construtor de consultas do Laravel `field->key` causa erro de sintaxe


Não há nada de errado com sua consulta. É o seu ambiente.

Problema


MySqlGrammar traduz o field->key notação nos nomes dos campos (no lado do Laravel) em field->'$.key' -style extrações (no lado do 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);
}

Acabei de confirmar que o MariaDB não suporta o -> operador de extração como um alias para o JSON_EXTRACT() função. No entanto, a mesma consulta funciona em um servidor MySQL 5.7 vanilla.

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

Uma consulta que usa o -> operador de extração:
SELECT payload->"$.b" FROM test;

falha no MariaDB 10.2.8 enquanto produz um 2 correto contra um servidor MySQL 5.7.19.

Soluções


A solução certa depende do que você está usando na produção.

Substituir MariaDB


Se você estiver usando MySQL, substitua MariaDB por MySQL em seu ambiente de desenvolvimento. Em uma máquina macOS gerenciada pelo homebrew, seria tão fácil quanto:
brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql

seus dados permanecerão intactos.

Reescreva suas consultas


No entanto, se você estiver usando o MariaDB em produção, precisará reescrever suas consultas para usar JSON_EXTRACT() funcionar como Elias já mencionado . Como você pode ver, você precisa ser muito mais detalhado com a API do Laravel.

A consulta acima seria:
SELECT JSON_EXTRACT(payload, "$.b") FROM test;