Вставка переменной в сырой SQL-запрос Laravel
Я нахожусь внутри функции в контроллере.
Итак, из формы я получаю значение для переменной, скажем:
$x = "whatever";
Затем мне нужно встроить эту переменную (а значит, и ее значение) в оператор WHERE. Если я жестко закодирую значение, это даст правильный результат, но я попытался всеми способами вставить эту переменную безуспешно. Что ж, если предположить, что мне удастся использовать эту переменную, тогда мне придется изучить привязку, чтобы избежать внедрения SQL, но пока, я бы сказал, посмотреть, можно ли использовать эту переменную в запросе.
Я пробовал, двойные кавычки, конкатенация. $vx . фигурные скобки {$x}, переменная обычная, как эта переменная $, но в некоторых случаях выдает синтаксические ошибки (конкатенация) или, если я просто встраиваю переменную, например, где author = $x, она говорит мне, что может не найти столбец с именем $ x
$x = "whatever";
$results = DB::select(DB::raw('SELECT
t.id, t.AvgStyle, r.RateDesc
FROM (
SELECT
p.id, ROUND(AVG(s.Value)) AS AvgStyle
FROM posts p
INNER JOIN styles s
ON s.post_id = p.id
WHERE author = $x
GROUP BY p.id
) t
INNER JOIN rates r
ON r.digit = t.AvgStyle'
));
2 ответа
Кажется, это простая проблема интерполяции переменных PHP.
DB:: raw хочет буквально RAW sql. Итак, есть пара проблем, которые необходимо исправить в передаваемой вами строке SQL.
- PHP Переменная интерполяция (вставка переменных в строку) происходит только если вы используете двойные кавычки вокруг строки. В одинарных кавычках он становится строковой константой.
- Если Author - это тип char/varchar, то синтаксис SQL требует кавычек вокруг строки в вашем выражении RAW SQL. Querybuilders обычно заботятся об этих проблемах для вас, но вы обходите их.
Таким образом, "фиксированная" версия этого будет:
$x = "whatever";
$results = DB::select(DB::raw("SELECT
t.id, t.AvgStyle, r.RateDesc
FROM (
SELECT
p.id, ROUND(AVG(s.Value)) AS AvgStyle
FROM posts p
INNER JOIN styles s
ON s.post_id = p.id
WHERE author = '$x'
GROUP BY p.id
) t
INNER JOIN rates r
ON r.digit = t.AvgStyle"
));
Как и любая интерполяция, это открывает вам возможность внедрения SQL, если интерполируемая переменная происходит из пользовательского ввода. Из исходного вопроса неясно, является ли это проблемой.
DB:: raw имеет опцию, которая позволяет вам вместо этого передавать массив параметров, который по своей природе безопасен для внедрения SQL. В этом случае решение будет:
$x = "whatever";
$results = DB::select(DB::raw("SELECT
t.id, t.AvgStyle, r.RateDesc
FROM (
SELECT
p.id, ROUND(AVG(s.Value)) AS AvgStyle
FROM posts p
INNER JOIN styles s
ON s.post_id = p.id
WHERE author = ':author'
GROUP BY p.id
) t
INNER JOIN rates r
ON r.digit = t.AvgStyle",
array('author' => $x)
));
Что касается этого урока
$results = DB::select( DB::raw("SELECT * FROM some_table WHERE some_col = :somevariable"), array(
'somevariable' => $someVariable,
));
Это один из примеров вставки переменной в необработанный sql laravel.
$query_result = Event::select(
DB::raw('(CASE WHEN status = "draft" THEN "draft"
WHEN events.end_time <= \''.$now.'\' THEN "closed"
ELSE "available"
END) AS status'))
->orderBy('status')
->get();