2012-03-26 5 views
2

Я пытаюсь вставить данные в таблицу, но если она уже существует в таблице, то ее не следует добавлять.
Это код, к которому я пришел, но он по-прежнему добавляет несколько данных с одинаковыми значениями.
Как вставить, если не существует

insert into nol_art_izm([ART_ID],[DAT]) 
    select distinct 
     v.id_art, {fn now()} 
    from 
     openxml(@hDoc, '/art_kompl/nol_voac') with #vc xd 
     inner join nol_voac v on xd.id_art = v.id_art 
    where 
     not exists(select * from nol_art_izm where nol_art_izm.art_id=xd.id_art) 


Я хочу, что нет какой-либо дублируют "ART_ID" значения

+0

Ваш запрос кажется, хорошо для меня. Вы получаете дубликаты в 'select separate' part? Моя версия sql-сервера получает значение now() один раз, но я не уверен, что это всегда так. –

+0

@Nikola Вставляет в таблицу значения «ART_ID» в таблице – Brezhnews

+0

В этом случае вы можете рассмотреть «GROUP BY v.id_art» и выбрать агрегатную функцию для '{fn now()}' (например, 'max'). – GolfWolf

ответ

2

Попробуйте

insert into nol_art_izm([ART_ID],[DAT]) 
    select distinct 
     v.id_art, {fn now()} 
    from 
     openxml(@hDoc, '/art_kompl/nol_voac') with #vc xd 
     inner join nol_voac v on xd.id_art = v.id_art 
     left join nol_art_izm n on n.art_id = v.id_art 
    where n.art_id is null 

Update:

Попробуйте использовать GROUP BY, чтобы избежать дублирования id_art значений :

insert into nol_art_izm([ART_ID],[DAT]) 
    select 
     v.id_art, MAX({fn now()}) 
    from 
     openxml(@hDoc, '/art_kompl/nol_voac') with #vc xd 
     inner join nol_voac v on xd.id_art = v.id_art 
    where 
     not exists(select * from nol_art_izm where nol_art_izm.art_id=xd.id_art) 
    group by v.id_art 

Пожалуйста, не то, что я выбрал функцию MAX для агрегирования {fn now()} значения (в случае, если есть еще такие значения в id_art). Возможно, вы захотите использовать другую функцию.

+0

В непростительных случаях объединение может быть хуже, чем полусоединение OP, поскольку существует риск дублирования данных, если в 'nol_art_izm.art_id' есть уже дубликаты –

+0

@LukasEder. Вы правы в этом. Решение 'MERGE' выглядит идеально, спасибо, что поделились им. +1 – GolfWolf

+0

работал с группой – Brezhnews

7

Примечание: Этот ответ будет работать только с SQL Server 2008 ...

Используйте MERGE заявление. Преимущество заявления MERGE состоит в том, что он четко выражает намерение вставить только в том случае, если еще нет соответствия. Для будущих читателей это может быть полезно, поскольку альтернативы с участием INSERT .. SELECT немного сложнее расшифровать.

-- This is where you're "merging" data into 
MERGE INTO nol_art_izm dst 

-- This is your merge data source 
USING (
    -- Use DISTINCT here, to prevent possible duplicates from the below INNER JOIN 
    SELECT DISTINCT v.id_art 
    FROM openxml(@hDoc, '/art_kompl/nol_voac') with #vc xd 
    INNER JOIN nol_voac v on xd.id_art = v.id_art 
) src 

-- This is your "join" condition, used to decide whether to perform an 
-- INSERT or UPDATE 
ON (dst.art_id = src.id_art) 

-- When source and target don't match (see ON clause), perform an insert 
WHEN NOT MATCHED THEN INSERT ([ART_ID],[DAT]) 
    VALUES (src.id_art, {fn now()}) 

Это утверждение опускает пункт WHEN MATCHED THEN UPDATE, так как вы заинтересованы только в выполнении INSERTs, не UPDATEs

+0

Когда я использую ваш метод, он показывает мне ошибку: «Msg 102, уровень 15, состояние 1, процедура INSERT_UPDATE_ARTIKULS_KOMPLEKTS_XML, строка 574 Неправильный синтаксис рядом с« MERGE ».» Не могу понять, почему. – Brezhnews

+0

@Brezhnews: «MERGE» был представлен с SQL Server 2008. Какую версию вы используете? –

+0

Тогда это, кажется, проблема, потому что я использую SQL Server 2005. Есть ли что-то подобное в SQL Server 2005? – Brezhnews

Смежные вопросы