Как написать запросы INSERT IF NOT EXISTS в SQL Server 2005

#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