Привязка параметров конструктора запросов Laravel

Я пытаюсь связать одно и то же значение с некоторым параметром в необработанном запросе (Laravel 5.2)

//this is a non practical example ,only for clarify the question

DB::table('users as u')
->select('id')
->whereRaw('u.id > ? or u.id < ? or u.id = ?',[2,2,2])
->first();

есть ли способ связать одни и те же параметры сразу (предотвратить дублирование значений в [2,2,2])?


person alex    schedule 12.03.2016    source источник
comment
Всегда ли вы знаете, что будет много заполнителей, или вы хотите заполнить все заполнители в запросе одним и тем же значением, независимо от их количества?   -  person tremby    schedule 13.03.2016
comment
В моем случае я знаю, сколько заполнителей будет там, и особенно в этом примере все они тоже одинаковы. Я пробовал :=someparameter или :someparameter разделить заполнители по имени, но это не сработало. похоже, только ? действителен!   -  person alex    schedule 13.03.2016
comment
Есть ли какая-то конкретная причина, по которой вы используете whereRaw? Будет ли действительным ответ, который его переписывает без whereRaw?   -  person tremby    schedule 13.03.2016


Ответы (1)


Используйте именованные параметры. Они описаны в документации в разделе Выполнение необработанных запросов SQL на странице базы данных в подзаголовке Использование именованных привязок. Цитата:

Вместо использования ? для представления привязок параметров вы можете выполнить запрос, используя именованные привязки:

$results = DB::select('select * from users where id = :id', ['id' => 1]);

В вашем случае вы должны иметь возможность запустить это:

DB::table('users as u')
    ->select('id')
    ->whereRaw('u.id > :id or u.id < :id or u.id = :id', [
        'id' => 2,
    ])
    ->first();

Но похоже, что Laravel выдает QueryException с сообщением Invalid parameter number. Я сообщил об этом как о ошибке.

Если вы действительно хотите использовать whereRaw, вы можете вместо этого построить свой массив параметров из переменной:

$id = 2;
DB::table('users as u')
    ->select('id')
    ->whereRaw('u.id > ? or u.id < ? or u.id = ?', [
        $id, $id, $id,
    ])
    ->first();

Или используйте array_fill, чтобы повторить значение для вас:

$id = 2;
DB::table('users as u')
    ->select('id')
    ->whereRaw('u.id > ? or u.id < ? or u.id = ?', array_fill(0, 3, $id))
    ->first();

Если вам не нужен whereRaw, вы можете вместо этого использовать другие функции построителя запросов и строить запрос по крупицам с параметром, поступающим из переменной:

$id = 2;
DB::table('users')
    ->select('id')
    ->where('id', '>', $id)
    ->orWhere('id', '<', $id)
    ->orWhere('id', $id)
    ->first();

Конструктор запросов довольно мощный, и для более сложной логики вы можете вкладывать замыкания. См. Несколько примеров в соответствующем разделе документации.

person tremby    schedule 13.03.2016
comment
спасибо. но это не работает. вы не можете использовать параметр с таким же именем в запросе. просто проверьте это: $results = DB::select('select * from users where id = :id or id > :id', ['id' => 1]); он выдаст исключение - person alex; 13.03.2016
comment
Интересный. Мне это кажется ошибкой Laravel. Я сообщил об этом в трекере как laravel / framework # 12715. Я обновлю первую половину ответа, чтобы отразить это. А как насчет второй половины? - person tremby; 13.03.2016
comment
Мне казалось, что привязка параметров с именем laravel похожа на PHP. Кажется, я был неправ, или, может быть, это ошибка, как вы сказали. ваш ответ вторая половина - это то, что я использую, это нормально! жду ответа на отчет об ошибке ... - person alex; 13.03.2016
comment
Вы не можете использовать один и тот же параметр несколько раз. Также убедитесь, что порядок совпадает: например, DB::select('select * from users where id = :id2 or id > :id1', ['id1' => 1, 'id2' => 2]) свяжет id2=1 и id2=1 - person ursuleacv; 15.03.2017
comment
@ursuleacv, ты прочитал весь ответ? Кроме того, я думаю, что в вашем фрагменте кода есть опечатка. Предполагая, что вы хотели ввести id2=1 и id1=2, это звучит как еще одна ошибка - это ошибка в Laravel или где? - person tremby; 16.03.2017
comment
@tremby, да ты прав я имел ввиду id2=1 и id1=2. Я думаю, что при привязке Laravel проигнорирует имена и создаст массив типа [0=>1, 1=>2] - person ursuleacv; 17.03.2017
comment
@ursuleacv, вы проверяли это, чтобы подтвердить это? Я бы подумал, что это определенно еще одна ошибка Laravel, если так. - person tremby; 18.03.2017
comment
@tremby, я конвертирую проект из Yii в Laravel и получаю неверные результаты запроса. Потом я заметил это странное поведение. У меня сейчас нет времени. Постараюсь в выходные воспроизвести баг. - person ursuleacv; 18.03.2017