Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите новичку с циклом  [new]
andreych
Member

Откуда: Мурманск
Сообщений: 189
В связи с "импортозамещением" перегоняют с 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]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
Kopelly
Member

Откуда: Красноярск
Сообщений: 286
Update t2
Set sname = rec.sname
From t1 rec
join t2 on t2.id = rec.id
4 июл 19, 10:20    [21920537]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
iap
Member

Откуда: Москва
Сообщений: 46862
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]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6612
iap,
подскажите
автор
NOT EXISTS(SELECT t2.[name] INTERSECT SELECT t1.[name])

такое живёт лучше чем t2.[name] <> t1.[name], без индексов и тп?
ну и значительно шире вариант
4 июл 19, 10:32    [21920545]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
andreych
Member

Откуда: Мурманск
Сообщений: 189
Спасибо, понял куда копать
4 июл 19, 10:37    [21920554]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
iap
Member

Откуда: Москва
Сообщений: 46862
TaPaK
iap,
подскажите
автор
NOT EXISTS(SELECT t2.[name] INTERSECT SELECT t1.[name])

такое живёт лучше чем t2.[name] <> t1.[name], без индексов и тп?
ну и значительно шире вариант
По крайней мере NULL здесь не равен NULL.
И да, используется индекс, если он есть.
Мы тут как-то это обсуждали несколько лет назад.

Может, 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]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6612
iap
TaPaK
iap,
подскажите
пропущено...

такое живёт лучше чем t2.[name] <> t1.[name], без индексов и тп?
ну и значительно шире вариант
По крайней мере NULL здесь не равен NULL.
И да, используется индекс, если он есть.
Мы тут как-то это обсуждали несколько лет назад.

Может, 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 и быстрее отработает, но запись громоздкая.

ясно
красота сейчас мало интересует, именно update не ключевых полей
4 июл 19, 10:40    [21920559]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
invm
Member

Откуда: Москва
Сообщений: 8802
TaPaK,

Если грубо, то только вариант exists(select a, b, c intersect select d, e, а) может быть преобразован оптимизатором в обычные предикаты. Соответственно, сохранится профит от индексов.

ЗЫ: Сугубо личный опыт.
4 июл 19, 11:03    [21920582]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
iap
Member

Откуда: Москва
Сообщений: 46862
invm
TaPaK,

Если грубо, то только вариант exists(select a, b, c intersect select d, e, а) может быть преобразован оптимизатором в обычные предикаты. Соответственно, сохранится профит от индексов.

ЗЫ: Сугубо личный опыт.
А NOT EXISTS() не прокатит?
4 июл 19, 11:35    [21920607]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
invm
Member

Откуда: Москва
Сообщений: 8802
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]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
Yuri Abele
Member

Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe
Сообщений: 1651
andreych,

присмотитесь к MERGE. Он позволяет отдим запросом, в идеале даже за один проход построить полную SCD-2 логику. Т.е. обновить (если изменились) общие строки, добавить отсутствующие и удалить лишние.

P.S. MERGE, к тому же, является частью ANSI SQL
4 июл 19, 13:45    [21920731]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
Yuri Abele
Member

Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe
Сообщений: 1651
MERGE (Transact-SQL)
4 июл 19, 13:46    [21920735]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
iap
Member

Откуда: Москва
Сообщений: 46862
Yuri Abele
andreych,

присмотитесь к MERGE. Он позволяет отдим запросом, в идеале даже за один проход построить полную SCD-2 логику. Т.е. обновить (если изменились) общие строки, добавить отсутствующие и удалить лишние.

P.S. MERGE, к тому же, является частью ANSI SQL
Но не в таком полном виде, как предложил Microsoft.
Кажется, там не прописан DELETE. Хотя, может, я отстал.
4 июл 19, 13:48    [21920737]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 6821
iap,

WHEN NOT MATCHED BY SOURCE DELETE, например.
4 июл 19, 13:55    [21920746]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
Yuri Abele
Member

Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe
Сообщений: 1651
iap
P.S. MERGE, к тому же, является частью ANSI SQL
Но не в таком полном виде, как предложил Microsoft.
Кажется, там не прописан DELETE. Хотя, может, я отстал.[/quote]
Да не, DELETE-то возможен и в ANSI, а вот в MSSQL добавлена возможность проверить на каком из концов отсутствует. Т.е. NOT MATCHED by SOURCE
4 июл 19, 13:57    [21920748]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
Yuri Abele
Member

Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe
Сообщений: 1651
Владтслав опередил :-)
4 июл 19, 13:58    [21920750]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
court
Member

Откуда:
Сообщений: 1805
Владислав Колосов
iap,

WHEN NOT MATCHED BY SOURCE DELETE, например.
имхо, iap говорил про стандарт, про ANSI SQL
А в нём, похоже, всё пока ограничивается INSERT / UPDATE

Merge (SQL)
4 июл 19, 15:15    [21920837]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3076
court,

Ну что вы, по вашей же ссылке, первая строка:
автор
It was officially introduced in the SQL:2003 standard, and expanded in the SQL:2008 standard.
4 июл 19, 15:18    [21920839]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
Yuri Abele
Member

Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe
Сообщений: 1651
Ну да и хрен с ним. Задачу решает и чудно!
4 июл 19, 15:21    [21920842]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
court
Member

Откуда:
Сообщений: 1805
Ennor Tiegael
court,

Ну что вы, по вашей же ссылке, первая строка:
автор
It was officially introduced in the SQL:2003 standard, and expanded in the SQL:2008 standard.

Да, я тоже на это "расширено" обратил внимание, но нигде не нашел, в чем же выглядело это "расширение" :)
А так как статья по ссылке представляет (я так понимаю) описание посл.версии, то видимо расширение не относилось к добавлению DELETE

имхо
4 июл 19, 16:31    [21920912]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
court
Member

Откуда:
Сообщений: 1805
court
А так как статья по ссылке представляет (я так понимаю) описание посл.версии, то видимо расширение не относилось к добавлению DELETE
тем более, что ниже, говорится про реализации в разных СУБД, и там, конкретно про MS SQL сказано так
Microsoft SQL Server extends with supporting guards and also with supporting Left Join via WHEN NOT MATCHED BY SOURCE clauses.
4 июл 19, 16:34    [21920916]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
Yuri Abele
Member

Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe
Сообщений: 1651
с версии 2014, как минмум, MERGE работает в полном объеме. Всё, приняли и забыли

P.S. Вот зря я ANSI SQL упомянул! Понесло народ совсем вдаль от темы топика.
4 июл 19, 16:40    [21920931]     Ответить | Цитировать Сообщить модератору
 Re: Помогите новичку с циклом  [new]
court
Member

Откуда:
Сообщений: 1805
Yuri Abele
с версии 2014, как минмум, MERGE работает в полном объеме. Всё, приняли и забыли

P.S. Вот зря я ANSI SQL упомянул! Понесло народ совсем вдаль от темы топика.
MERGE с первой же версии, с 2008, в МС СКЛ работает в полном объеме (INSERT / UPDATE / DELETE)
И это есть гуд :)

Просто интересно, почему в ANSI стандарте не сделали так же ?
Реально ж удобнее когда есть сразу три "пути" синхронизации в одном операторе ...
4 июл 19, 16:44    [21920943]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить