用于在Laravel / Eloquent中使用临时表中的新值更新行的SQL查询

时间:2013-11-13 22:09:03

标签: laravel laravel-4 eloquent

我希望根据源表A更新表B,这样如果找到新记录,我们可以插入它,否则如果有任何值已更改则更新记录。如何使用eloquent在laravel 4中编写查询?

Table A                                  Table B
=======                                  =======

Name         | Color                     Name         | Color
----------------------                   ----------------------
Mickey Mouse | grey                      Mickey Mouse | red
Donald Duck2 | green                     Donald Duck  | blue
Donald Duck  | blue                      Minnie       | red
Goofy        | black
Minnie       | red

在此示例中,表B应插入Goofy和Donald Duck2行,行mickey鼠标应使用新的灰色颜色进行更新。

1 个答案:

答案 0 :(得分:2)

这应该有效:

$a = A::all(); 

foreach($a as $current)
{ 
  $b = B::where("name", "=", $current->name)->first();
  if(!$b) $b = new B; 

  if($b->name != $current->name)
  {
   $b->name = $current->name; 
   $b->save(); 
 }
} 

或更优化:

$a = A::all(); 
// using this script: http://stackoverflow.com/questions/12050892/array-mapping-in-php-w ith-keys

   $aFolded = array_reduce($a, function(&$result, $item){ 
                                $result[$item->name] = $item->color;
                                return $result;
                               }, array());

// so we now have array ( name => color, name2 => color2 ) 

$b = B::with("a", "name")->get(); // might recheck with laravel doc
foreach($b as $updateMe)
{
  if($updateMe->color != $aFolded[$b->name])
  {
   $updateMe->color = $aFolded[$b->name]; 
   $updateMe->save();
   unset($aFolded[$b->name]); 
  }
}
// after this $aFolded will only contain the names which do not exist in b so we can just insert them all (maybe the insert query could be better) 
foreach($aFolded as $name => $color)
{
 DB::table("B")->insert(array("name" => $name, "color" => $color));  
}