#sql #sql-server #sql-server-2005
#sql #sql-сервер #sql-server-2005
Вопрос:
Я подключаю две базы данных для переноса данных. Я хочу проверить, существует ли запись из таблицы первой базы данных во второй базе данных.
Т.е. из пользовательской таблицы исходной базы данных я хочу перенести данные в пользовательскую таблицу целевой базы данных.
Как написать запрос, используя if not exists?
Комментарии:
1. Какая версия стандартного SQL?
Merge
является стандартным SQL, но поддерживается не всеми СУБД
Ответ №1:
insert into myTable
select * from myOldTable ot
where NOT EXISTS (select 1 from mytable t where t.ID = ot.ID)
Возможно, было бы лучше записать это как join
insert into myTable
select ot.*
from myOldTable ot
LEFT JOIN mtTable t
ON ot.ID = t.ID
WHERE t.ID IS NULL
или, в зависимости от вашей базы данных, слияние может быть лучше, есть много вариантов
Комментарии:
1. Для обоих этих запросов существует вероятность возникновения условий гонки, поэтому OP потребуется уникальное ограничение или дополнительные подсказки по блокировке.
2. @Martin, вы правы, добавление
WITH (SERIALIZABLE, UPDLOCK)
должно решить эту проблему, я полагаю3. На самом деле только что заметил, что Андомар указывает, что это для переноса данных, поэтому оператору, возможно, не нужно беспокоиться об этом.
Ответ №2:
Я нахожу следующий синтаксис самым простым для чтения:
insert TargetTable
(col1, col2)
from SourceTable as source
where not exists
(
select *
from TargetTable as duplicate
where source.col1 = duplicate.col1
and source.col2 = duplicate.col2
)
Обычно вам не нужно беспокоиться о параллелизме во время переноса данных. Если вы это сделаете, вы можете указать подсказки блокировки, подобные with (tablock)
или выше transaction isolation level
. Или вы можете использовать merge
, как предложено, но это имеет довольно запутанный синтаксис.
Ответ №3:
SQL2003 определяет MERGE
, в противном случае вы можете выполнить an INSERT INTO ... SELECT
и в SELECT
вы должны LEFT JOIN
в таблице назначения использовать естественный ключ в ON
предикате, а затем просто вставить WHERE <column> IS NULL
.
Комментарии:
1. 1 но похоже, что вопрос теперь отредактирован для ссылки на SQL Server 2005, а не на «стандартный SQL»
2. Мой ответ не зависит от SQL Server.
Ответ №4:
select * from db1.schema1.table1
intersect
select * from db2.schema2.table2