Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Der JSON-Selektor „field->key“ des Abfrageerstellers von Laravel verursacht einen Syntaxfehler

An deiner Anfrage ist nichts auszusetzen. Es ist Ihre Umgebung.

Problem

Laravels MySqlGrammar übersetzt den field->key Notation in Feldnamen (auf Laravel-Seite) in field->'$.key' -style-Extraktionen (auf MySQL-Seite):

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

Ich habe gerade bestätigt, dass MariaDB die -> Extraktionsoperator als Alias ​​für den JSON_EXTRACT() Funktion. Dieselbe Abfrage funktioniert jedoch mit einem Vanilla MySQL 5.7-Server.

Unter der Annahme dieses test Tabelle:

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

Eine Abfrage, die -> verwendet Extraktionsoperator:

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

schlägt mit MariaDB 10.2.8 fehl, während es einen korrekten 2 ergibt gegen einen MySQL 5.7.19-Server.

Lösungen

Die richtige Lösung hängt davon ab, was Sie in der Produktion verwenden.

MariaDB ersetzen

Wenn Sie MySQL verwenden, ersetzen Sie MariaDB in Ihrer Entwicklungsumgebung durch MySQL. Auf einem von Homebrew verwalteten macOS-Rechner wäre es so einfach wie:

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

Ihre Daten bleiben intakt.

Schreiben Sie Ihre Abfragen neu

Wenn Sie jedoch MariaDB in der Produktion verwenden, müssen Sie Ihre Abfragen neu schreiben, um JSON_EXTRACT() zu verwenden Funktion als Elias bereits erwähnt . Wie Sie sehen können, müssen Sie mit der Laravel-API viel ausführlicher sein.

Die obige Abfrage wäre:

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