Это можно сделать с помощью MERGE
. Допустим, у вас есть ключевой столбец ID
и два столбца col_a
и col_b
(необходимо указать имена столбцов в операторах обновления), тогда оператор будет выглядеть следующим образом:
MERGE INTO MyTable as Target
USING (SELECT * FROM
(VALUES (1, 2, 3), (2, 2, 4), (3, 4, 5))
AS s (ID, col_a, col_b)
) AS Source
ON Target.ID=Source.ID
WHEN NOT MATCHED THEN
INSERT (ID, col_a, col_b) VALUES (Source.ID, Source.col_a, Source.col_b)
WHEN MATCHED THEN
UPDATE SET col_a=Source.col_a, col_b=Source.col_b;
Вы можете попробовать его на rextester.com / IONFW62765 .
По сути, я создаю Source
таблицу «на лету», используя список значений, который вы хотите upsert . Затем, когда вы объединяете таблицу Source
с Target
, вы можете проверить условие MATCHED
(Target.ID=Source.ID
) в каждой строке (тогда как при использовании простого условия IF <exists> INSERT (...) ELSE UPDATE (...)
вы будете ограничены одной строкой). ).
В python с pyodbc
это должно выглядеть примерно так:
import pyodbc
insert_values = [(1, 2, 3), (2, 2, 4), (3, 4, 5)]
table_name = 'my_table'
key_col = 'ID'
col_a = 'col_a'
col_b = 'col_b'
cnxn = pyodbc.connect(...)
cursor = cnxn.cursor()
cursor.execute(('MERGE INTO {table_name} as Target '
'USING (SELECT * FROM '
'(VALUES {vals}) '
'AS s ({k}, {a}, {b}) '
') AS Source '
'ON Target.ID=Source.ID '
'WHEN NOT MATCHED THEN '
'INSERT ({k}, {a}, {b}) VALUES (Source.{k}, Source.{a}, Source.{b}) '
'WHEN MATCHED THEN '
'UPDATE SET {k}=Source.{a}, col_b=Source.{b};'
.format(table_name=table_name,
vals=','.join([str(i) for i in insert_values]),
k=key_col,
a=col_a,
b=col_b)))
cursor.commit()
Подробнее о MERGE
можно прочитать в документах по SQL Server .