Подтвердить что ты не робот

T SQL-пример объединения, необходимый для понимания

Следующее:

MERGE dbo.commissions_history AS target
USING (SELECT @amount, @requestID) AS source (amount, request)
ON (target.request = source.request)
WHEN MATCHED THEN
    UPDATE SET amount = source.amount
WHEN NOT MATCHED THEN
    INSERT (request, amount)
    VALUES (source.request, source.amount);

из qaru.site/info/104540/... - довольно изящный способ сделать вставку/обновление (и удалить с помощью некоторой дополнительной работы). Мне трудно следовать, хотя даже после некоторых поисковых запросов.

Кто-то может:

  • объясните это немного простыми словами - документация MSDN исказила мой мозг в этом случае.
  • показать мне, как он может быть изменен, чтобы пользователь мог вводить значения для суммы и запроса вместо того, чтобы их выбрали из другого местоположения базы данных?

В принципе, я хотел бы использовать это для вставки/обновления из приложения С# с информацией, полученной из файлов XML, которые я получаю. Итак, мне нужно понять, как я могу сформулировать запрос вручную, чтобы получить мои проанализированные данные в базе данных с помощью этого механизма.

4b9b3361

Ответ 1

Если вы не знакомы с join statements, тогда вам нужно начать. Понимание того, как работают соединения, является ключом к остальным. Когда вы знакомы с объединениями, то понимание слияния проще всего, рассматривая его как полное соединение с инструкциями о том, что делать для строк, которые выполняют или не соответствуют.

Итак, используя предоставленный пример кода, можно посмотреть таблицу commissions_history

|  Amount  |   Request  |   <other fields  |
--------------------------------------------
|  12.00   |   1234     |   <other data    |
|  14.00   |   1235     |   <other data    |
|  15.00   |   1236     |   <other data    |

Оператор слияния создает полное соединение между таблицей, называемой "target", и выражением, которое возвращает таблицу (или набор результатов, который логически очень похож на таблицу, подобную CTE), называемую "источником".

В приведенном примере он использует переменные в качестве источника, который мы предположим, был установлен пользователем или передан как параметр.

DECLARE @Amount Decimal = 18.00;
DECLARE @Request Int = 1234;

MERGE dbo.commissions_history AS target       
USING (SELECT @amount, @requestID) AS source (amount, request)       
ON (target.request = source.request)   

Создает следующий результирующий набор, когда считается объединением.

|  Amount  |   Request  |   <other fields  | Source.Amount | Source.Request  |
------------------------------------------------------------------------------
|  12.00   |   1234     |   <other data    |   18.00       |     1234        |
|  14.00   |   1235     |   <other data    |   null        |     null        |
|  15.00   |   1236     |   <other data    |   null        |     null        |

Использование инструкций о том, что делать с целью при условии, что совпадение найдено.

WHEN MATCHED THEN        
UPDATE SET amount = source.amount    

Итоговая целевая таблица теперь выглядит следующим образом. Строка с запросом 1234 обновляется до 18.

|  Amount  |   Request  |   <other fields  |
--------------------------------------------
|  18.00   |   1234     |   <other data    |
|  14.00   |   1235     |   <other data    |
|  15.00   |   1236     |   <other data    |

Поскольку матч не нашел ничего другого. Но скажем, что значения из источника были такими.

DECLARE @Amount Decimal = 18.00;
DECLARE @Request Int = 1239;

Итоговое соединение будет выглядеть так:

|  Amount  |   Request  |   <other fields  | Source.Amount | Source.Request  |
------------------------------------------------------------------------------
|  12.00   |   1234     |   <other data    |   null        |     null        |
|  14.00   |   1235     |   <other data    |   null        |     null        |
|  15.00   |   1236     |   <other data    |   null        |     null        |
|  null    |   null     |   null           |   18.00       |     1239        |

Так как совпадающая строка не найдена в целевой, оператор выполняет другое предложение.

WHEN NOT MATCHED THEN                                 
INSERT (request, amount)                                 
VALUES (source.request, source.amount);  

Результат в целевой таблице, которая теперь выглядит следующим образом:

|  Amount  |   Request  |   <other fields  |
--------------------------------------------
|  12.00   |   1234     |   <other data    |
|  14.00   |   1235     |   <other data    |
|  15.00   |   1236     |   <other data    |
|  18.00   |   1239     |   <other data    |

Операторы слияния истинный потенциал - это когда источником и целью являются большие таблицы. Поскольку он может делать большое количество обновлений и/или вставок для каждой строки с помощью простого простого оператора.

Последняя заметка. Важно иметь в виду, что not matched по умолчанию соответствует полному предложению not matched by target, однако вы можете указать not matched by source вместо или в дополнение к предложению по умолчанию. Оператор слияния поддерживает оба типа несоответствия (записи в источнике не в целевом объекте или записи в целевом объекте не в источнике, как определено в разделе on). Вы можете найти полную документацию, ограничения и полный синтаксис в MSDN.

Ответ 2

В данном примере ответа вы сделали

DECLARE @Request Int

но вызывая его в SQL следующим образом:

SELECT @amount, @requestID

Другим было бы именование и вызов переменных одинаково:

@amount vs. Amount -> @Amount & Amount