sql >> Databáze >  >> RDS >> Mysql

Selektor `field->key` v nástroji pro tvorbu dotazů Laravelu JSON způsobuje chybu syntaxe

Na vašem dotazu není nic špatného. Je to vaše prostředí.

Problém

Laravelův MySqlGrammar přeloží field->key zápis v názvech polí (na straně Laravelu) do field->'$.key' -style extrakce (na straně 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);
}

Právě jsem potvrdil, že MariaDB nepodporuje -> operátor extrakce jako alias k JSON_EXTRACT() funkce. Stejný dotaz však funguje proti vanilla serveru MySQL 5.7.

Za předpokladu tohoto test tabulka:

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

Dotaz, který používá -> operátor extrakce:

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

selže proti MariaDB 10.2.8, zatímco dává správný 2 proti serveru MySQL 5.7.19.

Řešení

Správné řešení závisí na tom, co používáte při výrobě.

Nahradit MariaDB

Pokud používáte MySQL, nahraďte MariaDB ve svém vývojovém prostředí MySQL. Na počítači macOS spravovaném homebrew by to bylo stejně snadné jako:

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

vaše data zůstanou nedotčena.

Přepište své dotazy

Pokud však používáte MariaDB v produkci, musíte své dotazy přepsat tak, aby používali JSON_EXTRACT() fungovat jako již zmíněný Elias . Jak vidíte, musíte být s Laravel API mnohem podrobnější.

Výše uvedený dotaz by byl:

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


  1. při aktualizaci duplicitního klíče s podmínkou?

  2. #1025 - Chyba při přejmenování (errno:150) v mysql

  3. Nejbližší zápas, část 1

  4. Jak získat celkový počet výsledků, když je v dotazu LIMIT?