laravel이 mysql only_full_group_by 문제를 해결하는 방법에 대해

藏色散人
풀어 주다: 2021-01-26 09:10:55
앞으로
3006명이 탐색했습니다.

MYSQL only_Full_group_BY 문제를 해결하는 방법을 소개합니다. 필요한 친구들에게 도움이 되길 바랍니다! MySQL 5.7 이후에는 only_full_group_by가 기본적으로 활성화되어 SQL 감지가 더욱 엄격해지며 이로 인해 다음과 같은 오류가 보고됩니다.

SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'edu.t_sounds.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
로그인 후 복사
이 문제를 해결하기 위해 많은 우회가 필요했습니다. 온라인에서 찾은 방법대로

Solution

sql_mode를 확인하세요

select @@GLOBAL.sql_mode;SELECT @@SESSION.sql_mode
로그인 후 복사

먼저 mysql 설정파일인 my.cnf를 확인해서 수정해주세요. ONLY_FULL_GROUP_BY

[mysqld]sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
로그인 후 복사

, 그럼 하자 계속해서 mysq l을 생각해 보세요. 서버 구성과 클라이언트 구성을 구별하려면 [client] 구성을 추가하세요

[client]sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
로그인 후 복사

mysql을 다시 시작하고 MySQL 도구에서 sql_mode를 확인하세요. 결과는 실제로 구성과 동일하지만 프로그램은 여전히 ​​보고합니다. 같은 오류

다시 검색해보니 갑자기 글로벌 세션의 문제, 즉 기사 머리 부분에 sql_mode를 쿼리하는 두 문장의 차이점을 확인해 보겠습니다.

mysql을 설정하는 방법은 두 가지가 있습니다. 변수, 하나는 전역 구성, 즉 전역적으로 작동하는 전역입니다. 현재 연결에서만 작동하는 세션 구성 세션



laravel이 현재 연결에 sql_mode를 설정했을 수 있습니까?

laravel 프로그램이 sql_mode

$result = \DB::select('SELECT @@GLOBAL.sql_mode');
print_r($result);exit;
结果:
STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

$result = \DB::select('SELECT @@SESSION.sql_mode');
print_r($result);exit;
结果:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
로그인 후 복사
를 인쇄하면 프로그램이 설정되었습니다. false로 설정하면 문제가 원활하게 해결됩니다
'strict' => false,
로그인 후 복사

이렇게 하면 문제가 해결될 수 있지만 기술적인 측면에서 무슨 일이 일어나고 있는지 파악해야 합니다. 직접 false로 설정하고 싶지는 않습니다.

vendor/laravel/framework/src/ILLuminate/Database 폴더에서 strict를 검색하고 핵심 코드를 직접 찾으세요.

파일: Vendor/laravel/framework/src/ ILLuminate/Database/Connectors/MySqlConnector.php
protected function setModes(PDO $connection, array $config){
    if (isset($config['modes'])) {
        $this->setCustomModes($connection, $config);
    } elseif (isset($config['strict'])) {
        if ($config['strict']) {
            $connection->prepare($this->strictMode($connection))->execute();
        } else {
            $connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
        }
    }}
로그인 후 복사
The 첫 번째 판단은 모드 구성이 있는지 직접 확인하는 것입니다. 그렇다면 이것을

    사용하여
  • 'modes' => ['STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_pISION_BY_ZERO', 'NO_AUTO_CREATE_USER', 'NO_ENGINE_SUBSTITUTION'],
    로그인 후 복사
  • 테스트를 수행하고 문제를 직접 해결하십시오.

루트 검색 정신으로 하단의 정신으로 계속 읽으십시오.

strict = true이면

은 프로그램에서 하드 코딩된 sql_mode를 직접 설정합니다. Laravel은 mysql 8.0.11을 다른 버전과 구별합니다

protected function strictMode(PDO $connection)
{
    if (version_compare($connection->getAttribute(PDO::ATTR_SERVER_VERSION), '8.0.11') >= 0) {
        return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
    }

    return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'";
}
로그인 후 복사

그리고 strict = false이면 직접 설정된 sql_mode가 NO_ENGINE_SUBSTITUTION

$connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
로그인 후 복사

으로 설정됩니다. 여기서 문제는 완전히 해결되었습니다

최종 해결책

'strict' => true,
'modes' => ['STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_DIVISION_BY_ZERO', 'NO_AUTO_CREATE_USER', 'NO_ENGINE_SUBSTITUTION'],
로그인 후 복사

은 strict = true를 유지하고 모드 옵션을 추가하며 내부 매개변수는 laravel의 기본 구성이지만 ONLY_FULL_GROUP_BY

만 제거합니다. 요약: 많은 우회를 한 후 많은 시간을 들여 마침내 문제가 해결되었고 mysql 구성을 수정할 필요도 없었습니다

위 내용은 laravel이 mysql only_full_group_by 문제를 해결하는 방법에 대해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:learnku.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿