简体   繁体   English

Laravel MySQL,其中封包无法按预期工作

[英]Laravel MySQL whereIn Closure Not Working As Expected

Can anyone help to explain why one of the following Laravel queries works and the other doesn't? 谁能帮助解释为什么以下Laravel查询之一有效而另一个无效?

The first that works: 第一个有效:

$array = ( 1, 2, 3 ,4 );
$query->whereIn( 'status_id', $array );

This works as expected. 这按预期工作。 However, when I try and pass a function to build my array: 但是,当我尝试传递一个函数来构建数组时:

$query->whereIn( 'status_id', function() use ( $statuses ){
    $status_array = array();
    foreach( $statuses as $status ){
         $status_array[] = $status->status_id;
    }

    return $status_array;
});

I get the following error: 我收到以下错误:

General error: 1096 No tables used (SQL: select * from jobs where status_id in (select *)) 常规错误:1096未使用任何表(SQL:从*(选择*)中有status_id jobs中选择*)

I have checked to see that the array I am building in the closure is the same as the array that works, and it is. 我检查了一下,我在闭包中建立的数组与起作用的数组相同,就是这样。 Am I missing something fundamental regarding whereIn() and it's closure functions? 我是否缺少有关whereIn()及其关闭函数的基本知识? Can I even pass a closure to whereIn()? 我什至可以将闭包传递给whereIn()吗?

As a related answer, instead of running a loop to generate your list - just have Laravel do it for you 作为一个相关的答案,而不是运行循环来生成您的列表- 只需让Laravel为您做

 $status_array= DB::table('status')->lists('status_id');

then use it 然后用它

 $query->whereIn( 'status_id', $status_array );

When you use a closure in whereIn() , Laravel will think that you will be doing a sub query. 当您在whereIn()使用闭包时,Laravel会认为您将进行子查询。 Hence you see another select inside your in in your error message. 因此,你看到另一个select你的内部in你的错误消息。

You'll need to parse your array of values before passing to the whereIn() 您需要先解析值数组,然后whereIn()

foreach ($statuses as $status) {
     $status_array[] = $status->status_id;
}

$query->whereIn('status_id', $status_array);

Extra: See reference to Laravel source. 附加:请参阅对Laravel来源的参考。

Illuminate\\Database\\Query\\Builder : Illuminate \\ Database \\ Query \\ Builder

public function whereIn($column, $values, $boolean = 'and', $not = false)
{
    ...

    if ($values instanceof Closure)
    {
        return $this->whereInSub($column, $values, $boolean, $not);
    }
}

which calls whereInSub() : 哪个调用whereInSub()

protected function whereInSub($column, Closure $callback, $boolean, $not)
{
    $type = $not ? 'NotInSub' : 'InSub';

    // To create the exists sub-select, we will actually create a query and call the
    // provided callback with the query so the developer may set any of the query
    // conditions they want for the in clause, then we'll put it in this array.
    call_user_func($callback, $query = $this->newQuery());

    $this->wheres[] = compact('type', 'column', 'query', 'boolean');

    $this->mergeBindings($query);

    return $this;
}

I think your function returns an array like this one: 我认为您的函数返回的数组是这样的:

[ 0 => status_id_value_0,
  1 => status_id_value_1, 
  ...
] 

Try to return an array_values($status_array) to check it. 尝试返回一个array_values($status_array)进行检查。

Anyway, try this one too: 无论如何,也可以尝试以下方法:

$query->whereIn( 'status_id', 
                 array_values(
                     array_map(
                         function($pos){return $pos->status_id;},
                         $statuses
                     )
                 )
               ); 

I hope it works fine for you. 希望它对您有用。

You need to convert comma separated value to array before passing to whereIN. 您需要先将逗号分隔的值转换为数组,然后再传递给whereIN。

and this is also good for any dynamic content 这也适用于任何动态内容

    foreach ($statuses as $status) {
         $status_array[] = $status->status_id;
    }
    $query->whereIn('status_id', $status_array);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM