Вопрос пользователя заключается в необходимости обновления или вставки записи в таблицу с использованием инструкции MERGE в MS SQL Server. Это позволяет избежать проверки существования записи и изменения DML (Data Manipulation Language) запросов. Примером такого подхода может служить вставка или обновление данных с одними и теми же параметрами запроса, что обеспечивает более высокую производительность за счет оптимизации компилятора хранимых процедур.
Пользователь работает в среде Delphi XE10 с базой данных MS SQL 2012 и использует таблицу map_locations. Задача состоит в том, чтобы вставлять новые записи в таблицу, если они не нарушают первичный ключ, и обновлять их, если запись уже существует по ключу.
Подробный разбор решения:
Для решения задачи можно использовать инструкцию MERGE, которая позволяет объединить операции обновления и вставки в одну транзакцию. Пример запроса на T-SQL:
MERGE INTO [dbo].[map_locations] AS [target]
USING (SELECT @loc_min_lat, @loc_min_lng, @loc_id, @center) AS [source]([loc_min_lat], [loc_min_lng], [loc_id], [center])
ON ([target].[loc_min_lat] = [source].[loc_min_lat] AND [target].[loc_min_lng] = [source].[loc_min_lng])
WHEN MATCHED THEN
UPDATE SET [loc_min_lat] = [source].[loc_min_lat], [loc_min_lng] = [source].[loc_min_lng], [loc_id] = [source].[loc_id], [center] = [source].[center]
WHEN NOT MATCHED THEN
INSERT ([loc_min_lat], [loc_min_lng], [loc_id], [center])
VALUES ([source].[loc_min_lat], [source].[loc_min_lng], [source].[loc_id], [source].[center]);
Здесь @loc_min_lat, @loc_min_lng, @loc_id, @center - это параметры, которые вы передаете в хранимую процедуру из вашего приложения на Delphi.
Из-за ограничений в тексте ответа, поэтому давайте приведем пример реализации подобной процедуры в Delphi:
procedure TForm1.MergeRecord(const AMinLat, AMinLng, AID: string; const ACenter: string);
var
SQLQuery: string;
begin
SQLQuery :=
'MERGE INTO [dbo].[map_locations] AS [target] ' +
'USING (SELECT ''' + AMinLat + ''', ''' + AMinLng + ''', ' + IntToStr(AID) + ', ''' + ACenter + ''' ) AS [source]([loc_min_lat], [loc_min_lng], [loc_id], [center]) ' +
'ON ([target].[loc_min_lat] = [source].[loc_min_lat] AND [target].[loc_min_lng] = [source].[loc_min_lng]) ' +
'WHEN MATCHED THEN ' +
'UPDATE SET [loc_min_lat] = [source].[loc_min_lat], [loc_min_lng] = [source].[loc_min_lng], [loc_id] = [source].[loc_id], [center] = [source].[center] ' +
'WHEN NOT MATCHED THEN ' +
'INSERT ([loc_min_lat], [loc_min_lng], [loc_id], [center]) ' +
'VALUES ([source].[loc_min_lat], [source].[loc_min_lng], [source].[loc_id], [source].[center]);';
// Выполнение SQL запроса через компонент TSQLConnection
end;
Важно, что для защиты от SQL-инъекций, все параметры в запросе должны быть параметризованы, что достигается путем использования методов ParamByName или PrepareAndExec компонента TSQLConnection.
Заключение:
Использование инструкции MERGE позволяет эффективно обновлять и вставлять записи в таблицу, минимизируя количество операций над базой данных. Применение параметризованных запросов и хранимых процедур обеспечивает дополнительную безопасность и производительность.
Инструкция MERGE в MS SQL Server используется для оптимизации обновления и вставки записей в таблицу, позволяя выполнять эти операции в одной транзакции с использованием параметризованных запросов.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS