Mysql
 sql >> Base de données >  >> RDS >> Mysql

Le sélecteur JSON du constructeur de requêtes de Laravel `champ-> clé` provoque une erreur de syntaxe

Il n'y a rien de mal avec votre requête. C'est votre environnement.

Problème

MySqlGrammar traduit le field->key notation dans les noms de champs (côté Laravel) dans field->'$.key' -style extractions (côté 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);
}

Je viens de confirmer que MariaDB ne supporte pas le -> opérateur d'extraction comme alias du JSON_EXTRACT() fonction. Cependant, la même requête fonctionne sur un serveur MySQL 5.7 vanilla.

En supposant ce test tableau :

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

Une requête qui utilise le -> opérateur d'extraction :

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

échoue contre MariaDB 10.2.8 alors qu'il donne un 2 correct contre un serveur MySQL 5.7.19.

Solutions

La bonne solution dépend de ce que vous utilisez en production.

Remplacer MariaDB

Si vous utilisez MySQL, remplacez MariaDB par MySQL dans votre environnement de développement. Sur une machine macOS gérée par homebrew, ce serait aussi simple que :

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

vos données resteront intactes.

Réécrivez vos requêtes

Cependant, si vous utilisez MariaDB en production, vous devez réécrire vos requêtes pour utiliser JSON_EXTRACT() fonctionner comme Elias déjà mentionné . Comme vous pouvez le voir, vous devez être beaucoup plus verbeux avec l'API Laravel.

La requête ci-dessus serait :

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