小编典典

在原始SQL查询Laravel中插入变量

sql

我在控制器的函数中。

因此,从表单中,我得到了一个变量的值,说:

$x = "whatever";

然后,我需要在WHERE语句中嵌入该变量(即它的值)。如果我对值进行硬编码,它将带来正确的结果,但是我已经尝试了各种方法来插入该变量而没有成功。好吧,假设我设法使用了该变量,那么我将不得不研究绑定以避免SQL注入,但是到目前为止,我要说的是,看看该变量是否可以在查询中使用。

我已经试过了,双引号,串联。$ vx。,花括号{$ x},像$
variable这样的普通变量,但是在某些情况下(并置)会产生语法错误,或者如果我只是在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'
                           ));

阅读 187

收藏
2021-03-23

共1个答案

小编典典

这似乎是一个简单的PHP变量插值问题。

DB::raw()想要字面上的 原始 SQL。因此,您需要在传递的SQL字符串中解决几个问题。

  1. 仅当在字符串周围使用双引号时,才会发生PHP变量插值(将变量注入到字符串中)。用单引号将其变为字符串常量。
  2. 如果Author是char/varchar,则SQL语法要求在原始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 = '$x'    
                       GROUP BY p.id
                   ) t
                   INNER JOIN rates r
                       ON r.digit = t.AvgStyle"
                   ));

像所有插值一样,如果要插值的变量来自用户输入,则可以打开SQL注入的可能性。从最初的问题尚不清楚这是否是一个问题。

DB::select()有一个选项,使您可以传递本质上可以防止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)
                   );
2021-03-23