Eloquent: на псевдоним из внешнего запроса нельзя ссылаться в подзапросе - PullRequest
0 голосов
/ 28 января 2019

У меня следующий запрос:

DB::table('dining_tables as dt')
        ->whereNotExists(function($query){
            $query
                ->from('booking_allocations as ba')
                ->join('time_slots as ts', 'ba.slot_id', '=', 'ts.id')
                ->where('ba.booking_date', '=', '2019-01-27')
                ->where('ts.start_time', '>=', '12:00 PM')
                ->where('ts.end_time', '<=', '1:00 PM')
                ->where('ba.table_id', '=', 'dt.id')
                ->select(DB::raw('null'));
        })
        ->where('dt.capacity', '>=', 4)
        ->select('id')
        ->limit(1)
        ->get();

Обратите внимание, что псевдоним dt, созданный во внешнем запросе, ссылается в подзапросе в следующей строке:

->where('ba.table_id', '=', 'dt.id')

Это оставляет меня со следующей ошибкой:

Освещение / База данных / QueryException с сообщением 'SQLSTATE [22P02]: Неверное текстовое представление: 7 ОШИБКА: неверный синтаксис ввода для целого числа: "dt.id" (SQL: выберите «id» из «Dining_tables» в качестве «dt», где не существует (выберите «null» из «booking_allocations» в качестве «ba», внутреннее соединение «time_slots», как «ts» на «ba». «slot_id» = «ts». "id "где" ba "." booking_date "= 2019-01-27 и" ts "." start_time "> = 12:00 PM и" ts "." end_time "<= 1:00 PM и" ba "."table_id "= dt.id) и" dt ". "acity"> = 4 limit 1) '

Мне потребовалось полдня, чтобы понять, что ошибка может быть обойдена этим кодом замены:

->where('ba.table_id', '=', DB::raw('dt.id'))

ПРИМЕЧАНИЕ. Обтекание DB::raw() вокруг псевдонима-нарушителя.

Теперь запрос работает, как и ожидалось.Я хотел бы понять, что здесь может происходить.

1 Ответ

0 голосов
/ 28 января 2019

whereNotExists внутренне выполняет отдельный запрос:

https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Query/Builder.php#L1435 https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Query/Builder.php#L1404 https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Query/Builder.php#L2772

dt известно только «высшему»Экземпляр строителя БД.

Из-за этого db builder в вашем вложенном каталоге where обрабатывает его как строку, а поскольку ba.table_id является целым числом, значение типа string нельзя использовать в этом контексте.

Когда вы используете db raw - он просто помещает его как есть в sql, где он работает как положено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...