2016-01-20 106 views
2

我需要更新db(PostgreSQL)中的單個匹配記錄,但Limit方法不適用於Update方法。此代碼將更新所有匹配Where條件而不是單條記錄的記錄。Laravel 5更新單行限制不起作用

DB::table("records") 
    ->where('need_moderate','=','no') 
    ->where('locked_per_time','<',$date_now->format("Y-m-d H:i:s")) 
    ->limit(1) 
    ->update(["locked_per_time"=>$locked_per->format("Y-m-d H:i:s"),'locked_by'=>$mdkey]); 

我如何解決此所以只有單一的記錄將被更新?

回答

1

OracleMySQL更新語句不同,使用LIMIT直接在PostgreSQL update statements是不可能的。因此,將limit(1)方法鏈接到查詢生成器實例什麼都不做,因爲負責編譯查詢的Laravel的PostgresGrammar類的compileUpdate方法只編譯where語句。

但是,您可以通過使用僅返回將更新的一行的子查詢來解決此問題。像這樣的東西應該工作:

DB::table("records")->whereIn('id', function ($query) use ($date_now) { 
    $query->from('records') 
      ->select('id') 
      ->where('need_moderate', '=', 'no') 
      ->where('locked_per_time', '<', $date_now->format("Y-m-d H:i:s")) 
      ->limit(1); 
})->update(["locked_per_time" => $locked_per->format("Y-m-d H:i:s"), 'locked_by' => $mdkey]); 

whereIn('id', ...)條件假設你的表有一個名爲id列可以作爲一個唯一的標識符,因此它可以發現在子查詢符合您的條件的第一行。

+0

不幸的是代碼無法正常工作。即使有2-4個線程,相同的記錄仍然釋放到不同的線程。我假設在第一個線程更新之前執行第二個線程的內部選擇。 我將不勝感激。 – Nelex

+0

我不確定我是否理解。請提供更詳細的背景介紹您希望更新過程如何工作。 – Bogdan

+0

對於每個查詢,我們通過更改其locked_per_time來更新記錄。在此之後,我們從這個記錄中獲取數據。雖然當前日期小於locked_per_time,但該記錄不應該對其他線程有效,並且永遠不會執行兩次。但即使有我在運行多個線程時提供的代碼,它們也會在第一個線程更新之前以某種方式獲得相同的記錄locked_per_time – Nelex