在我 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 檔案中建立預存程序,因此我必須搜尋其他選項。
我能找到的在純 SQL 中模擬 Eloquent 的 updateOrInsert() 功能的最簡單解決方案是將問題分成兩部分:
實際情況如下:
-- 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中文網其他相關文章!