programing

Larabel의 쿼리 빌더 JSON 셀렉터 'field->key'가 구문 오류를 발생시킵니다.

goodsources 2022. 10. 21. 23:01
반응형

Larabel의 쿼리 빌더 JSON 셀렉터 'field->key'가 구문 오류를 발생시킵니다.

그래서, 나는 질문하고 싶다.notifications특정 ID와 비교함으로써 Laravel에 있는 테이블data기둥.이렇게 해서data열은 다음과 같습니다.

{
    "Message": "some message",
    "id": 3
}

이제 ID가 3인 알림을 모두 선택해야 합니다.제가 하려고 했던 방법은 다음과 같습니다.

DB::table('notifications')->where('data->id', '3')->get();

그러나 이로 인해 다음 오류가 발생합니다.

SQLSTATE [ 42000 ]:구문 오류 또는 액세스 위반: 1064 SQL 구문에 오류가 있습니다. MariaDB 서버 버전에 해당하는 설명서에서 '>'$"id' = ?' 근처에서 사용할 올바른 구문을 확인하십시오(SQL: 에서 * 선택).notifications어디에data->'$"id" = 3)

나 지금 제정신이 아닌데, 누가 좀 도와줄 수 있어?

당신의 질문에는 아무런 문제가 없습니다.고객의 환경입니다.

문제

Laravel's 번역:field->key필드명(라벨측)에서의 표기법field->'$.key'- 스타일 추출(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);
}

MariaDB가 함수에 대한 에일리어스로 추출 연산자를 지원하지 않는 것을 확인했습니다.그러나 동일한 쿼리는 바닐라 MySQL 5.7 서버에서도 작동합니다.

이렇게 가정하면test테이블:

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

를 사용하는 쿼리->추출 연산자:

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

MariaDB 10.2.8에 대해 실패하면 올바른 결과를 얻을 수 있습니다.2MySQL 5.7.19 서버에 접속합니다.

솔루션

적절한 솔루션은 실제 가동 환경에 어떤 솔루션을 사용하고 있는지에 따라 달라집니다.

마리아 교체DB

MySQL을 사용하는 경우 개발 환경에서 MariaDB를 MySQL로 대체합니다.홈브루가 관리하는 MacOS 머신에서는 다음과 같이 간단합니다.

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

데이터는 그대로 유지됩니다.

쿼리를 재작성하다

단, 운영 환경에서 MariaDB를 사용하는 경우 쿼리를 다시 작성하여 사용해야 합니다.JSON_EXTRACT()이미 언급한 엘리아스처럼 기능합니다.보다시피 Laravel API에서는 보다 상세하게 설명해야 합니다.

위의 쿼리는 다음과 같습니다.

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

Json 지원용 Laravel MariaDB 드라이버를 만들었습니다.입수처: ybr-nx/laravel-mariadb

문제는 MySQL만이 이 기능을 지원한다는 것입니다.->연산자, 그러면 쿼리는 MariaDB에서 실패합니다만,

MariaDBMySQL은 모두JSON_EXTRACT 함수는 JSON을 해석하고 값을 가져옵니다.

다음과 같은 쿼리를 수행하여 문제를 해결할 수 있습니다.

SELECT * FROM notifications WHERE JSON_EXTRACT(`notifications.data`, "$.id") = 5

Laravel의 Query Builder를 사용하려면DB::raw★★★★

DB::table('notifications')->where(DB::raw('JSON_EXTRACT(`notifications.data`, "$.id")'), '=', 3);

한번 해보고 틀리면 알려주세요.

주의:JSON_EXTRACT()는, 「」에서만 할 수 있습니다.MySQL >= 5.7 ★★★★★★★★★★★★★★★★★」MariaDB >= 10.2.3

@Sepehr 덕분에, 저는 이 제품이->하지 않습니다. MySQL Operator는 JSON을 사용합니다. :-)

는 ' ' '에 .->$data라는 이름의 var를 가지고 계신 것 같습니다.그렇다면 올바른 방법은 다음과 같습니다.

DB::table('notifications')->where($data->id, '3')->get();

또는 통지 관련 모델테이블이 있는 경우:

Notification::where($data->id, '3')->get();

경우,Model라고 합니다.Notification유언적 에 따름 (유언적 표기법에 )

그러나 모든 ID가 3인 것을 찾으려 하면 다음과 같이 됩니다.

DB::table('notifications')->where('id', '3')->get();

언급URL : https://stackoverflow.com/questions/46282286/laravels-query-builder-json-selector-field-key-causes-syntax-error

반응형