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

Откуда: Тверь
Сообщений: 9
SQL Server 2012

Есть две идентичные по структуре таблицы адресов TAdress и TAdress1:

Create table TAdress1
( Adress int identity (1,1) not null,
Country nvarchar(20),
City nvarchar(15),
Street nvarchar (15),
House nvarchar (5),
Room int,
Constraint PK_TAdress1 primary key (Adress),
);

В них внесены данные:

insert into TAdress (Country, City, Street, House,Room) values
( N'Россия', N'Санкт-Петербург', N'Московская', N'23', 11),
( N'Германия', N'Мюнхен', N'Восточная', N'12', null),
( N'Германия', N'Берлин', N'Карла Маркса', N'56', 3),
( N'Россия', N'Санкт-Петербург', N'Ленсовета', N'45а', 8),
( N'Белоруссия', N'Минск', N'Гагарина', N'29', null),
( N'Россия', N'Санкт-Петербург', N'Туполева', N'11', 4)
;

insert into TAdress1 (Country, City, Street, House,Room) values
( N'Россия', N'Санкт-Петербург', N'Московская', N'23', 11),
( N'Австрия', N'Берлин', N'Карла Маркса', N'56', 3),
( N'Россия', N'Санкт-Петербург', N'Ленсовета', N'45а', 8),
( N'СНГ', N'Минск', N'Гагарина', N'29', null)

Можно ли как-то запросом Merge
а) исправить несовпадения стран, изменив соотв. записи в таблице TAdress1?
б) дополнить таблицу TAdress1 недостающими строками из TAdress?

Сделать а и б одной инструкцией Merge?

Заранее спасибо

P.S. Можете посоветовать где посмотреть подробно для-ничего-не-понявнших про Merge? MSDN, гайд по серверу и Петкович не спасли ((
29 сен 14, 12:51    [16633540]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по Merge  [new]
Glory
Member

Откуда:
Сообщений: 104760
silvi
Сделать а и б одной инструкцией Merge?

И по какому полю вы предлагаете связывать таблицы ? По Adress ?
29 сен 14, 12:53    [16633560]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по Merge  [new]
iap
Member

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

а таблица TAdress где определена? Кстати, глупые америкашки там два d пишут.

Так прокатит?
SET IDENTITY_INSERT TAdress1 ON;
MERGE TAdress1 T USING TAdress S ON T.Adress=S.Adress
WHEN MATCHED AND NOT EXISTS(SELECT T.* INTERSECT SELECT S.*)
THEN UPDATE SET
 Country=S.Country
,City=S.City
,Street=S.Street
,House=S.House
,Room=S.Room
WHEN NOT MATCHED INSERT(Adress,Country,City,Street,House,Room)VALUES(S.Adress,S.Country,S.City,S.Street,S.House,S.Room);
SET IDENTITY_INSERT TAdress1 OFF;
29 сен 14, 13:13    [16633681]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по Merge  [new]
iap
Member

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

а удалять из TAdress1 Adress, которого в TAdress нет, не надо, да?
29 сен 14, 13:15    [16633692]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по Merge  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
Но если в TAdress1 всё время приходится вставлять те же строки, что и в TAdress,
то встаёт вопрос: а зачем поле TAdress1.Adress вообще имеет свойство IDENTITY ??
29 сен 14, 13:26    [16633746]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по Merge  [new]
Станислав Клевцов
Member

Откуда: Krasnodar-Russia
Сообщений: 566
silvi,

Кратко об операторе MERGE

В отличие от универсальных операторов INSERT, UPDATE, DELETE, оператор MERGE удобен для использования в определенных сценариях.
В этих сценариях есть две таблицы.

  • Первая — это целевая таблица, которая содержит основное множество строк.
  • Вторая промежуточная — эта таблица с такой же структурой как и первая, содержащая новые\измененные строки.

    Задачей оператора является соединение (MERGE) данных из промежуточной и целевой таблиц.
    После выполнения оператора целевая таблица будет обновлена в соответствии с заданными правилами

  • (например, новые строки добавить, старые обновить).

    При выполнении операции строки из целевой таблицы будут сопоставлены со строками из промежуточной таблицы.
    Для этого необходимо определить предикат (определяется в блоке USING конструкции MERGE), способ сопоставления.
    Каждая строка из временной таблицы будет сопоставлена с каждой строкой из целевой таблицы, для каждой комбинации будет вычислен предикат.

    Предикат, как правило, это сравнение по ключу. В результате у нас получится три множества строк.
  • Строки, которые есть как в целевой, так и в промежуточной таблице (MATCHED). К этой группе можно применить — UPDATE, т.е. обновить существующие строки
  • Строки, которые есть только в промежуточной таблице, но отсутсвуют в целевой (NOT MATCHED). Для этой группы можно сделать INSERT.

    Эти два множества позволят задать правила обработки строк.

    Стоит отметить, что оператор реализован так, что для каждой строки во временной таблице должна существовать только одна строка в целевой.

    После выполнения MERGE необходимо осуществить DELETE строк, которые являются более неактуальными для этого используется джоин промежуточной и целевой таблицы.... удаляются записи,которых нет в промежуточной таблице, но которые остались в целевой.
  • 29 сен 14, 15:33    [16634492]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    silvi
    Member

    Откуда: Тверь
    Сообщений: 9
    Glory, я пока не могу ответить на вопрос в силу недостаточного понимания merge. Серия экспериментов убедила меня в том, что это не правильное решение. Однако merge везде указывается как, в том числе, средство согласования таблиц и я стремлюсь в этом разобраться.
    И если верить тому, что написали про Merge здесь (Станислав), как-то так она и должна работать. Или нет?...

    iap, TAdress определена там же, ее структура 1:1 как у TAdress1. Это мои тестовые таблички для экспериментов - эмулируют, скажем, две рассогласованные таблицы. Если в этом что-то концептуально не правильно, скажите мне, пожалуйста. Спасибо за корректировку, я запомню. Вот так выглядит вторая на всякий случай:

    Create table TAdress
    ( Adress int identity (1,1) not null,
    Country nvarchar(20),
    City nvarchar(15),
    Street nvarchar (15),
    House nvarchar (5),
    Room int,
    Сonstraint PK_TAdress primary key (Adress),
    constraint FK_TCountry foreign key (Country) references TCountry (Country) on update cascade
    );
    go

    Запрос к сожалению не работает : "Incorrect syntax near the keyword 'INSERT'." Но по ходу дела проблема в том, что сервер считает после Room=S.Room инструкция merge заканчивается - там подчеркивание грамматики и требует точку с запятой.

    Поле Adress играет роль суррогатного первичного ключа и наличествует в обоих таблицах. Если в этом есть что-то идеологически неправильное, скажите мне, пожалуйста.
    Или с сурогатным ключом не подойдет - нужно ключ из всех полей или он должен совпадать с ключем второй, обновленной таблицы, я правильно поняла?

    Станислав Клевцов, спасибо, стало немного лучше))
    По последнему моменту с удалением не актуальных строк. Это делается уже вне Merge, я правильно понимаю? Почему просто не удалить промежуточную таблицу вместо Join?
    29 сен 14, 20:59    [16636052]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    Glory
    Member

    Откуда:
    Сообщений: 104760
    silvi
    Glory, я пока не могу ответить на вопрос в силу недостаточного понимания merge.

    Т.е. вы не смогли достаточно понять синтаксис команды ?
    http://msdn.microsoft.com/en-us/library/bb510625.aspx
    Вот обязательные элементы команды
    MERGE <target_table>
    USING <table_source>
    ON <merge_search_condition>
    вы про них прочитали в хелпе ?

    Сообщение было отредактировано: 29 сен 14, 21:07
    29 сен 14, 21:06    [16636079]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    Станислав Клевцов
    Member

    Откуда: Krasnodar-Russia
    Сообщений: 566
    silvi
    По последнему моменту с удалением не актуальных строк. Это делается уже вне Merge, я правильно понимаю? Почему просто не удалить промежуточную таблицу вместо Join?


    Вы правильно понимаете. Удаление несуществующих записей в целевой таблице будет происходить уже вне MERGE.

    Если вы не удалите данные в целевой таблице, которых нет во временной, то целевая таблица будет хранить историю загрузки данных из временной таблицы.
    29 сен 14, 21:36    [16636179]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    silvi
    Member

    Откуда: Тверь
    Сообщений: 9
    Glory, нет, на таком уровне я догадалась. И до прихода сюда написала с десяток разных Merge на этих таблицах, соединяя их как раз по Adress (это же правильно, соединять по ключу в данном случае?...).
    Но они же убедили меня в том, что в данном конкретном случае привязка к идентификатору не всегда приводит к нужному результату - в силу разных на самом деле идентификаторов TAdress и TAdress1. Поэтому я и решила спросить здесь, чтобы разобраться, что я не так понимаю и можно ли как-то извернуться в данном конкретном случае.
    29 сен 14, 21:37    [16636184]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    silvi
    Member

    Откуда: Тверь
    Сообщений: 9
    Станислав Клевцов,
    вот тут не поняла до конца: если мы используем Update и вставляем строки в целевую таблицу, откуда в ней возьмутся другие данные -история загрузки из временной таблицы?
    в ней должно же быть три типа строк:
    1) которых нет во временной и они остались как есть
    2) которые есть во временной и они обновлены
    3) которые есть во временной и они вставлены
    так?
    или речь идет об удалении строк из первой категории?
    29 сен 14, 21:41    [16636200]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    Станислав Клевцов
    Member

    Откуда: Krasnodar-Russia
    Сообщений: 566
    silvi
    Станислав Клевцов,
    вот тут не поняла до конца: если мы используем Update и вставляем строки в целевую таблицу, откуда в ней возьмутся другие данные -история загрузки из временной таблицы?
    в ней должно же быть три типа строк:
    1) которых нет во временной и они остались как есть
    или речь идет об удалении строк из первой категории?


    Вы все правильно понимаете.
    Вам только нужно определиться с удалением несуществующие записи в целевой таблице, если данные во временной таблице будут считаться актуальными.
    29 сен 14, 21:57    [16636259]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    Станислав Клевцов
    Member

    Откуда: Krasnodar-Russia
    Сообщений: 566
    silvi
    Станислав Клевцов,
    1) которых нет во временной и они остались как есть
    2) которые есть во временной и они обновлены
    3) которые есть во временной и они вставлены
    так?
    или речь идет об удалении строк из первой категории?


    1. Если вам нужно, чтобы временная таблица и целевая таблица по кол-ву записей совпадали всегда, то после оператора MERGE удаляете только те записи из целевой таблицы, которых нет во временной.
    2. Если у вас во временной таблице хранится небольшая часть данных, которые необходимо добавить в целевую. Вы точно знаете , что у вас появятся новые записи,а часть старых записей изменится, то вам следует использовать только оператор MERGE.

    Либо вы собираетесь хранить историю (2)\ либо нет(1). Все зависит от вашей задачи. Надеюсь, что вы теперь понимаете, когда нужно использовать после оператора MERGE - > DELETE, а когда нет.
    29 сен 14, 22:18    [16636325]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    silvi
    Member

    Откуда: Тверь
    Сообщений: 9
    Станислав Клевцов, спасибо, с пониманием инструкции все стало намного лучше!
    29 сен 14, 22:36    [16636378]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    iap
    Member

    Откуда: Москва
    Сообщений: 47001
    silvi
    Запрос к сожалению не работает : "Incorrect syntax near the keyword 'INSERT'."
    THEN пропустил, кажется.
    WHEN NOT MATCHED THEN INSERT(Adress,Country,City,Street,House,Room)VALUES(S.Adress,S.Country,S.City,S.Street,S.House,S.Room);
    
    30 сен 14, 09:17    [16636940]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    silvi
    Member

    Откуда: Тверь
    Сообщений: 9
    iap,
    это не так. Я проверила еще тогда ((
    подчеркивания на скриншоте не показаны (Insert и конец Room) но ошибка внизу есть

    К сообщению приложен файл. Размер - 13Kb
    30 сен 14, 10:09    [16637128]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    Glory
    Member

    Откуда:
    Сообщений: 104760
    silvi
    подчеркивания на скриншоте не показаны (Insert и конец Room) но ошибка внизу есть

    А THEN перед INSERT все так же нет
    30 сен 14, 10:11    [16637137]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    iap
    Member

    Откуда: Москва
    Сообщений: 47001
    silvi
    iap,
    это не так. Я проверила еще тогда ((
    подчеркивания на скриншоте не показаны (Insert и конец Room) но ошибка внизу есть

    Картинка с другого сайта.
    Какие ещё подчёркивания?
    Там должен быть обязательный THEN!
    Так поставьте его туда, наконец.
    И если опять синтаксическая ошибка, то сервер снова скажет, какая и где.
    30 сен 14, 10:11    [16637139]     Ответить | Цитировать Сообщить модератору
     Re: Вопрос по Merge  [new]
    silvi
    Member

    Откуда: Тверь
    Сообщений: 9
    Спасибо, все поняла
    30 сен 14, 13:46    [16638450]     Ответить | Цитировать Сообщить модератору
    Все форумы / Microsoft SQL Server Ответить