在使用laravel插入数据之前检查数据库并避免重复
我试图在插入数据之前检查数据库以避免重复。 我将URL存储在数组中,然后将这些URL插入表的“链接”列中。 所以首先我要检查该列,是否设置相同的URL? 如果不是,则使用此代码插入数据。 这是我完整的数据库插入代码:
foreach ($outlineUrls  as $outlineUrl) {
    $html = file_get_contents($outlineUrl);
    $DOMParser = new \DOMDocument();
    $DOMParser->loadHTML($html);


    $changeForMyDB = [
                            'remote_id' => '',
                            'region' => '関西',
                            'link' => json_encode($outlineUrl),
                            'name' => '',
                            'price' => '',
                            'extend' => '',
                            'address' => '',
                            'hows_old' => '',
                            'rooms' => '',
                            'old' => '',
                            'entery' => '',
                            'balcon_m2' => '',
                            'company_name' => '',
                            'script_from' => ''
                        ];

            $allPTags = $DOMParser->getElementsByTagName('p');
            foreach($allPTags as $ptag){
                if($ptag->getAttribute('class') == 'c-name'){
                        $changeForMyDB['name'] = trim($ptag->nodeValue);
                }
            }

            $changeForMyDB['address'] = trim($DOMParser->getElementsByTagName('dd')[0]->nodeValue);

            $allTables = $DOMParser->getElementsByTagName('table');
            foreach($allTables as $table){
                foreach($table->getElementsByTagName('tr') as $tr){
                    $property = trim($tr->getElementsByTagName('th')[0]->nodeValue);
                    $value = trim($tr->getElementsByTagName('td')[0]->nodeValue);

                    switch ($property) {
                        case '物件名':
                            $changeForMyDB['name'] = $value;
                            break;
                        case '販売価格':
                            $changeForMyDB['price'] = $value;
                            break;
                        case '専有面積':
                            $changeForMyDB['extend'] = $value;
                            break;
                        case '所在地':
                            $changeForMyDB['address'] = $value;
                            break;
                        case '総戸数':
                            $changeForMyDB['hows_old'] = $value;
                            break;
                        case '間取り':
                            $changeForMyDB['rooms'] = $value;
                            break;
                        case '竣工時期':
                            $changeForMyDB['old'] = $value;
                            break;
                        case '管理会社':
                            $changeForMyDB['company_name'] = $value;
                            break;
                        case '入居時期':
                            $changeForMyDB['entery'] = $value;
                            break;
                        case '入居時期':
                            $changeForMyDB['entery'] = $value;
                            break;
                        case 'バルコニー面積':
                            $changeForMyDB['balcon_m2'] = $value;
                            break;
                        default:
                            # code...
                            break;
                    }
                }
            }

if(Estates::where('link','=',$outlineUrl)->count() > 0)
{

   $this->error('There is link.');

} else {

        Estates::insertGetId($changeForMyDB);

        $this->line('Data saved.');

       }

但问题就在这里。它没有检查就插入了数据! 你知道是什么问题吗?谢谢你的帮助。

dpnru86024
dpnru86024 我用完整的代码更新问题,你可以检查一下!
一年多之前 回复
dougaimian1143
dougaimian1143 您没有显示将URL插入表格的代码。
一年多之前 回复
dongqing314511
dongqing314511 请阅读Laravel的验证,您不必重新发明轮子。laravel.com/docs/5.7/validation
一年多之前 回复

1个回答

You can use the updateOrCreate() method to achieve the goal of only inserting if the record does not exist:

$estate = Estates::updateOrCreate(['link' =>  $outlineUrl], $changeForMyDB);

This will check if there is an Estate::where('link', '=', $outlineUrl). If none is found, it will create a new Estate´ and add all data from$changeForMyDBto it. If one exists, it will fetch it from the database, add all data from$changeForMyDB`. Then it will persist the changes. Read more about that here: https://laravel.com/docs/5.7/eloquent#other-creation-methods


To avoid issues with concurrent requests, you should also wrap your update within a database transaction. This ensures that the database has the same state when you checked for uniqueness as when you store your data.

DB::transaction(function () {
    $estate = Estates::updateOrCreate(['link' =>  $outlineUrl], $changeForMyDB);
});

If you don't want to update existing entries, use something like this:

DB::transaction(function () {
    if (Estates::where('link','=',$outlineUrl)->count() === 0) {
        $estate = Estates::create($changeForMyDB);
    }
});

Beware that Estates::create($data) and Estates::insert($data) are not the same. The create($data) function will create a model, fill it with the $data and return the persisted model. It will also fire all Eloquent events that are relevant for the create method. The insert($data) method on the other hand will not create an Eloquent model and will therefore also not fire any Eloquent events. It will directly insert the data into the database. This is more lightweight and faster, but you should keep that in mind.


If you want to check if the record already existed and report some kind of error, you can check with this:

if (!$estate->wasRecentlyCreated()) {
    // report error here
}
dsc80135
dsc80135 好的,谢谢你的答案很长,对不起负担。 由于你的回答,我理解这个问题。 如果没有数据,我想插入数据。 但是如果有数据,我想更新它并保留旧数据。 因为我需要使用一个旧数据的列。 我想我需要一个新的问题。
一年多之前 回复
douyan1927
douyan1927 我用我的整个代码队友更新问题,你能查一下吗?
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问