Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IF NOT EXISTS in Merge statement?

I want to do the following, when primary keys matched and if there are no rows with active 'Y' insert records. Is this possible?

I tried this:

-- Merge statement
MERGE INTO table1 AS DST
USING table2 AS SRC
ON (SRC.Code = DST.Code)

 --Existing records updated if data changes
WHEN MATCHED 
AND IF NOT EXISTS (WHERE active='Y' FROM table1 )

THEN
INSERT INTO table1 (colum)
SELECT value

+-------+-------------+--------+
| Code  | description | Active |
+-------+-------------+--------+
| AB    | just        |    |
|       |  something  | No     |
+-------+-------------+--------+

only when there is no active record with the same Code, I want to insert a record. The new record would look like this

+-------+-------------+--------+
| Code  | description | Active |
+-------+-------------+--------+
| AB    | something   |    |
|       | else        | YES    |
+-------+-------------+--------+

I hope that makes it more clear

edit: Never mind its not possible, I just got this error message: An action of type 'INSERT' is not allowed in the 'WHEN MATCHED' clause of a MERGE statement.

like image 670
R2D2 Avatar asked Nov 22 '11 10:11

R2D2


1 Answers

If I understand you correctly, insert rows from @T2 that is not already in @T1 where Active = 'y'.

declare @T1 table
(
  Code char(2),
  Descr varchar(10),
  Active char(1)
)

declare @T2 table
(
  Code char(2),
  Descr varchar(10)
)

insert into @T1 values
('1', 'Desc 1', 'y'),
('2', 'Desc 2', 'n')

insert into @T2 values
('1', 'Desc 1'),
('2', 'Desc 2'),
('3', 'Desc 3')

merge @T1 as D
using @T2 as S
on D.Code = S.Code and 
   D.Active = 'y'
when not matched then
  insert (Code, Descr, Active) 
    values (Code, Descr, 'y');

select *
from @T1

Result:

Code Descr      Active
---- ---------- ------
1    Desc 1     y
2    Desc 2     n
2    Desc 2     y
3    Desc 3     y

Row with Code 3 will also be inserted. If you did not want that, meaning that you only want to insert a row to @T1 if there already exist a row in @T2 with a match on code but Active = 'n' you could use this instead.

merge @T1 as D
using (select Code,
              Descr
       from @T2
       where Code in (select Code 
                      from @T1 
                      where Active = 'n')) as S
on D.Code = S.Code and 
   D.Active = 'y'
when not matched then
  insert (Code, Descr, Active) 
    values (Code, Descr, 'y');

Result:

Code Descr      Active
---- ---------- ------
1    Desc 1     y
2    Desc 2     n
2    Desc 2     y
like image 52
Mikael Eriksson Avatar answered Sep 20 '22 01:09

Mikael Eriksson