За свою семилетнюю карьеру программиста я большую часть времени взаимодействовал с SQL через ORM. Одна из особенностей Laravel Eloquent ORM, которую я считаю особенно полезной, — это метод updateOrInsert():
DB::table('posts') ->updateOrInsert( ['slug' => 'about'], // matching condition ['content' => 'Like and subscribe'] // created or updated values );
В приведенном выше примере Eloquent будет искать в таблице сообщений строку, где слаг равен «about». Если существует строка с этим ярлыком, Eloquent обновит содержимое этой строки на «Нравится и подписаться». Если строка не существует с этим ярлыком, Eloquent создаст новую строку со словом «о» и содержимым «Нравится и подписаться».
В настоящее время я пишу сценарий миграции для перемещения данных страницы со старого сайта WordPress на новый сайт WordPress. Скрипт подключается к базе данных старого сайта, затем создает файл SQL, который можно импортировать в базу данных нового сайта. На новом сайте уже есть некоторые страницы, которые были перемещены вручную, но их содержимое может быть устаревшим. Если страница уже существует на новом сайте, мы не хотим создавать ее снова: мы хотим обновить уже существующую страницу. Мы можем определить, существует ли страница, используя столбец post_name в базе данных WordPress, который соответствует URL-адресу страницы.
Если бы post_name было первичным ключом, мы могли бы выполнить что-то похожее на метод createOrUpdate() Eloquent, используя оператор REPLACE, но post_name не является первичным ключом.
Если бы post_name имело уникальное ограничение, мы могли бы выполнить что-то похожее на метод createOrUpdate() Eloquent, используя оператор INSERT ... ON DUPLICATE KEY UPDATE, но post_name не имеет уникального ограничения.
Ах, прелести WordPress.
Я изучил оператор IF MySQL, но оператор IF работает только в хранимых процедурах, триггерах и функциях. Мне не хотелось создавать в SQL-файле хранимые процедуры, которые я бы импортировал в базу данных нового сайта, поэтому пришлось искать другие варианты.
Самое простое решение, которое я смог найти для эмуляции функциональности updateOrInsert() Eloquent в чистом SQL, заключалось в том, чтобы разбить проблему на две части:
Вот как это выглядит на практике:
-- 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' );
ПРИМЕЧАНИЕ: В этом примере для краткости и ясности опущены многие из обязательных столбцов wp_posts WordPress.
Изучение оператора INSERT ... SELECT стало для меня моментом «ага». Предполагается использовать результаты запроса из другой таблицы для одновременного выполнения множества вставок. Однако вы можете использовать и злоупотреблять возможностями SQL, предоставляя свои собственные значения и выполняя вставку только в том случае, если сообщение с именем post_name «about» не существует.
Это самое элегантное и эффективное решение этой проблемы? Вероятно, нет. Но этого достаточно для однократной миграции сайта WordPress и позволяет обновлять или вставлять строку без необходимости использования хранимых процедур или какой-либо логики приложения. Надеюсь, этот пост поможет вам писать мощные запросы без помощи ORM.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3