Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
andreych Member Откуда: Мурманск Сообщений: 191 |
В связи с "импортозамещением" перегоняют с Oracle на MS SQL, хотя чего тут замещенного не понимаю. Ну ладно. Проблема такова. Есть две таблицы по структуре абсолютно одинаковы, периодически в одной нужно обновлять данные другой таблицы. В Oracle я сделал бы так for rec in ( select id, sname from t1 ) loop update t2 set t2.sname = rec.sname where t2.id = rec.id end loop Как такую конструкцию повторить в ms sql, конкретно 2012 сервер? В postgres в принципе аналогично, а вот с как то не срастается. |
4 июл 19, 10:12 [21920528] Ответить | Цитировать Сообщить модератору |
Kopelly Member Откуда: Красноярск Сообщений: 289 |
Update t2 Set sname = rec.sname From t1 rec join t2 on t2.id = rec.id |
4 июл 19, 10:20 [21920537] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
UPDATE t2 SET t2.[name]=t1.[name] FROM t2 JOIN t1 ON t2.id=t1.id WHERE NOT EXISTS(SELECT t2.[name] INTERSECT SELECT t1.[name]); |
4 июл 19, 10:27 [21920541] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6801 |
iap, подскажите
такое живёт лучше чем t2.[name] <> t1.[name], без индексов и тп? ну и значительно шире вариант |
||
4 июл 19, 10:32 [21920545] Ответить | Цитировать Сообщить модератору |
andreych Member Откуда: Мурманск Сообщений: 191 |
Спасибо, понял куда копать |
4 июл 19, 10:37 [21920554] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
И да, используется индекс, если он есть. Мы тут как-то это обсуждали несколько лет назад. Может, t2.[name] <> t1.[name] OR t2.[name] IS NULL AND t1.[name] IS NOT NULL OR t2.[name] IS NOT NULL AND t1.[name] IS NULL и быстрее отработает, но запись громоздкая. |
||||
4 июл 19, 10:38 [21920558] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6801 |
ясно красота сейчас мало интересует, именно update не ключевых полей |
||||
4 июл 19, 10:40 [21920559] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9646 |
TaPaK, Если грубо, то только вариант exists(select a, b, c intersect select d, e, а) может быть преобразован оптимизатором в обычные предикаты. Соответственно, сохранится профит от индексов. ЗЫ: Сугубо личный опыт. |
4 июл 19, 11:03 [21920582] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
|
||
4 июл 19, 11:35 [21920607] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9646 |
iap, Сравните: use tempdb; go create table dbo.t1 (id int identity primary key, f int, v int); create table dbo.t2 (id int identity primary key, f int, v int); create index IX_t1__f on dbo.t1 (f); create index IX_t2__f on dbo.t2 (f); go set statistics xml on; update a set v = b.v from dbo.t1 a join dbo.t2 b on b.id = a.id where exists(select a.f intersect select b.f); update a set v = b.v from dbo.t1 a join dbo.t2 b on b.id = a.id where not exists(select a.f intersect select b.f); set statistics xml off; go drop table dbo.t1, dbo.t2; go |
4 июл 19, 12:02 [21920629] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
andreych, присмотитесь к MERGE. Он позволяет отдим запросом, в идеале даже за один проход построить полную SCD-2 логику. Т.е. обновить (если изменились) общие строки, добавить отсутствующие и удалить лишние. P.S. MERGE, к тому же, является частью ANSI SQL |
4 июл 19, 13:45 [21920731] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
MERGE (Transact-SQL) |
4 июл 19, 13:46 [21920735] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47052 |
Кажется, там не прописан DELETE. Хотя, может, я отстал. |
||
4 июл 19, 13:48 [21920737] Ответить | Цитировать Сообщить модератору |
Владислав Колосов Member Откуда: Сообщений: 8350 |
iap, WHEN NOT MATCHED BY SOURCE DELETE, например. |
4 июл 19, 13:55 [21920746] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Кажется, там не прописан DELETE. Хотя, может, я отстал.[/quote] Да не, DELETE-то возможен и в ANSI, а вот в MSSQL добавлена возможность проверить на каком из концов отсутствует. Т.е. NOT MATCHED by SOURCE |
||
4 июл 19, 13:57 [21920748] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Владтслав опередил :-) |
4 июл 19, 13:58 [21920750] Ответить | Цитировать Сообщить модератору |
court Member Откуда: Сообщений: 2253 |
А в нём, похоже, всё пока ограничивается INSERT / UPDATE Merge (SQL) |
||
4 июл 19, 15:15 [21920837] Ответить | Цитировать Сообщить модератору |
Ennor Tiegael Member Откуда: Сообщений: 3348 |
court, Ну что вы, по вашей же ссылке, первая строка:
|
||
4 июл 19, 15:18 [21920839] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Ну да и хрен с ним. Задачу решает и чудно! |
4 июл 19, 15:21 [21920842] Ответить | Цитировать Сообщить модератору |
court Member Откуда: Сообщений: 2253 |
Да, я тоже на это "расширено" обратил внимание, но нигде не нашел, в чем же выглядело это "расширение" :) А так как статья по ссылке представляет (я так понимаю) описание посл.версии, то видимо расширение не относилось к добавлению DELETE имхо |
||||
4 июл 19, 16:31 [21920912] Ответить | Цитировать Сообщить модератору |
court Member Откуда: Сообщений: 2253 |
|
||||
4 июл 19, 16:34 [21920916] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
с версии 2014, как минмум, MERGE работает в полном объеме. Всё, приняли и забыли P.S. Вот зря я ANSI SQL упомянул! Понесло народ совсем вдаль от темы топика. |
4 июл 19, 16:40 [21920931] Ответить | Цитировать Сообщить модератору |
court Member Откуда: Сообщений: 2253 |
И это есть гуд :) Просто интересно, почему в ANSI стандарте не сделали так же ? Реально ж удобнее когда есть сразу три "пути" синхронизации в одном операторе ... |
||
4 июл 19, 16:44 [21920943] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |