Как вставить только если не существует - PullRequest
2 голосов
/ 26 марта 2012

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

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"

Ответы [ 2 ]

7 голосов
/ 26 марта 2012

Примечание : Этот ответ будет работать только с 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

2 голосов
/ 26 марта 2012

Попробуйте

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

Обновление:

Попробуйте использовать 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). Возможно, вы захотите использовать другую функцию.

...