簡體   English   中英

Laravel Eloquent,如何處理UNIQUE錯誤?

[英]Laravel Eloquent, how to handle UNIQUE error?

我有一個MySQL約束來確保復合鍵的唯一性。 在我的模型Foo插入新記錄時,我得到預期的錯誤:

$foo = new Foo(['foo' => 42, 'bar => 1]);
$foo->save();

錯誤:

SQLSTATE [23000]:完整性約束違規:1062重復條目'42'表示密鑰'唯一'...

避免此錯誤的一種解決方案是在插入之前查詢模型:

if (!Foo::where('foo', 42)->where('bar', 1)->first()) {
  $foo = new Foo(['foo' => 42, 'bar => 1]);
  $foo->save();
}

另一個是當preg_match(/UNIQUE/, $e->message)true時捕獲異常。

有沒有更好的解決方案?

編輯

我注意到在Illuminate\\Database\\Eloquent\\Builder Eloquent Illuminate\\Database\\Eloquent\\Builder Laravel無論如何都會進行雙重查詢,這有點令人傷心:

public function findOrNew($id, $columns = ['*'])
{
    if (! is_null($model = $this->find($id, $columns))) {
        return $model;
    }

    return $this->newModelInstance();
}

您可以使用firstOrCreate方法:

$foo = Foo::firstOrCreate(['foo' => 42, 'bar' => 1]);

這將在創建記錄之前檢查數據庫中是否存在記錄。 如果存在,它將返回記錄。

有關更多信息: https//laravel.com/docs/5.8/eloquent#inserting-and-updating-models

laravel為您提供了firstOrCreate函數,它首先檢查數據庫中是否存在該值,然后您還要使用updateOrCreate函數,以便更新某些值,但最重要的是,如果您只想處理唯一記錄,那么請檢查驗證規則,您將執行FormRequest並向該字段添加唯一規則,在該laravel之后為您提供錯誤消息,以便您在客戶端處理錯誤

驗證需要在Controller級別完成(如laravel Validator),最好是count()而不是first()

根據您在數據庫中存在實體時要執行的操作,有不同的解決方案。 例如,你可以做updateOrCreate()

$foo = App\Foo::updateOrCreate(['foo' => 42, 'bar' => 1]);

或拋出異常

在一般情況下,您應該使用錯誤代碼處理數據庫錯誤,而不是任何正則表達式。

在您的特定情況下,如果您打算覆蓋/更新現有數據,則可能更傾向於預先查詢或使用自動為您執行此操作的Laravel方法。

如果您希望一般預期錯誤並處理它,您應該執行以下操作:

try {
   $foo = new Foo(['foo' => 42, 'bar' => 1]);
   $foo->save();
} catch (\Exception $e) { // It's actually a QueryException but this works too
   if ($e->getCode() == 23000) {
       // Deal with duplicate key error  
   }
}

有關錯誤代碼的詳盡列表,請參閱https://dev.mysql.com/doc/refman/5.5/en/error-reference.html (但理想情況下,您只需處理幾個特定錯誤,非常具體的情況。

最后,SQL ON DUPLICATE KEY UPDATE也可能對您ON DUPLICATE KEY UPDATE ,但是如果您這樣做是為了靜默忽略新值,那么我建議您進行錯誤處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM