在資料庫中更新插入不使用主鍵或唯一約束的行

Linda Hamilton
發布: 2024-10-19 10:52:29
原創
257 人瀏覽過

Upsert a row in a DB that doesn

在我 7 年的程式設計師職涯中,我大部分時間都是透過 ORM 與 SQL 互動。我發現 Laravel 的 Eloquent ORM 的一個特別有用的功能是它的 updateOrInsert() 方法:

DB::table('posts')
    ->updateOrInsert(
        ['slug' => 'about'], // matching condition
        ['content' => 'Like and subscribe'] // created or updated values
    );
登入後複製

在上面的範例中,Eloquent 會在 posts 表中尋找 slug 等於「about」的行。如果存在帶有該 slug 的行,Eloquent 會將該行的內容更新為「按讚並訂閱」。如果行存在於該slug中,Eloquent將建立一個新行,其中包含「about」和「Like and subscribe」的內容。

問題:沒有主鍵或唯一約束

我目前正在編寫一個遷移腳本,用於將頁面資料從舊的 WordPress 網站移至新的 WordPress 網站。該腳本連接到舊網站的資料庫,然後建立一個可以匯入到新網站的資料庫中的 SQL 檔案。新網站已有一些已手動移動的頁面,但其內容可能已過時。當新網站上已經存在頁面時,我們不想再次建立它:我們想要更新已經存在的頁面。我們可以透過使用 WordPress 資料庫中的 post_name 欄位來確定頁面是否已經存在,該欄位對應於頁面的 URL slug。

如果 post_name 是主鍵,我們可以使用 REPLACE 語句完成類似 Eloquent 的 createOrUpdate() 方法的操作,但 post_name 不是主鍵。

如果 post_name 有唯一約束,我們可以使用 INSERT ... ON DUPLICATE KEY UPDATE 語句完成類似 Eloquent 的 createOrUpdate() 方法的運算,但 post_name 沒有唯一約束。

啊,WordPress 的樂趣。

我研究了 MySQL 的 IF 語句,但 IF 語句只適用於預存程序、觸發器和函數。我不想在要匯入到新網站資料庫的 SQL 檔案中建立預存程序,因此我必須搜尋其他選項。

解:2條語句

我能找到的在純 SQL 中模擬 Eloquent 的 updateOrInsert() 功能的最簡單解決方案是將問題分成兩部分:

  1. 使用符合的 slug 更新任何現有行。
  2. 如果沒有符合 slugs 的行,則建立一個新行。

實際情況如下:

-- Update the post if it already exists.

UPDATE wp_posts
SET post_type = 'page',
    post_title = 'About',
    post_content = 'Like and subscribe'
WHERE post_name = 'about';

-- Create a new post if it does not exist.

INSERT INTO wp_posts (post_name, post_type, post_title, post_content)
SELECT 'about', 'page', 'About', 'Like and subscribe'
WHERE NOT EXISTS (
    SELECT 1
    FROM wp_posts
    WHERE post_name = 'about'
);
登入後複製

注意:為了簡潔和清晰起見,此範例省略了許多 WordPress 所需的 wp_posts 欄位。

了解 INSERT ... SELECT 語句對我來說是「頓悟」時刻。它的目的是使用另一個表的查詢結果來一次執行多次插入。但是,您可以透過提供自己的值來使用和濫用 SQL 的功能,並且僅當 post_name 為「about」的貼文不存在時才執行插入。

這是解決這個問題最優雅、最有效的解決方案嗎?可能不會。但對於 WordPress 網站的一次性遷移來說,它已經足夠好了,而且它允許您更新或插入一行,而無需預存程序或任何應用程式邏輯。希望這篇文章能夠幫助您在不借助 ORM 的情況下編寫強大的查詢。

以上是在資料庫中更新插入不使用主鍵或唯一約束的行的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!