2011-09-07 12 views
18

Actualmente estoy usando el siguiente código de combinación para migrar la fecha de origen a destino. Tengo un nuevo requisito para extender el código a continuación para eliminar el registro de la fuente una vez que se realiza una actualización/inserción en el destino. Es esto posible utilizando fusionar (todos los ejemplos que veo en la red habían realizando del/de inserción/actualización en el objetivo no de la fuente)¿Cómo eliminar de la fuente con el comando MERGE en SQL Server 2008?

MERGE Target1 AS T 
USING Source1 AS S 
ON (T.EmployeeID = S.EmployeeID) 
WHEN NOT MATCHED BY TARGET AND S.EmployeeName LIKE 'S%' 
    THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName) 
WHEN MATCHED 
    THEN UPDATE SET T.EmployeeName = S.EmployeeName 
WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%' 
    THEN DELETE ; 
+1

No se puede hacer como parte de un único estado. Cada instrucción de modificación de datos solo realiza cambios en una sola tabla. –

+0

Gracias Damien. – nfa379

Respuesta

28

Usted puede utilizar la cláusula de salida para capturar las filas modificadas/insertadas a una variable de tabla y usar eso con una declaración de eliminación después de la combinación.

DECLARE @T TABLE(EmployeeID INT); 

MERGE Target1 AS T 
USING Source1 AS S 
ON (T.EmployeeID = S.EmployeeID) 
WHEN NOT MATCHED BY TARGET AND S.EmployeeName LIKE 'S%' 
    THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName) 
WHEN MATCHED 
    THEN UPDATE SET T.EmployeeName = S.EmployeeName 
WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%' 
    THEN DELETE 
OUTPUT S.EmployeeID INTO @T; 

DELETE Source1 
WHERE EmployeeID in (SELECT EmployeeID 
        FROM @T); 
2


Niza Reponse, pero su código va a eliminar la fila de su tabla de destino, aquí hay un exemple en los que se podrá eliminar las filas de su origen destino sin afectar a su tabla de destino:

if OBJECT_ID('audit.tmp1') IS NOT NULL 
    DROP TABLE audit.tmp1 

select * 
into audit.tmp1 
from 
(
select 1 id, 'aa' nom, convert(date,'2014-01-01') as dd UNION ALL 
select 2 id, 'bb' nom, convert(date,'2013-07-12') as dd UNION ALL 
select 3 id, 'cc' nom, convert(date,'2012-08-21') as dd UNION ALL 
select 4 id, 'dd' nom, convert(date,'2011-11-15') as dd UNION ALL 
select 5 id, 'ee' nom, convert(date,'2010-05-16') as dd) T 


if OBJECT_ID('audit.tmp2') IS NOT NULL 
DROP TABLE audit.tmp2 

select * 
into audit.tmp2 
from 
(
select 1 id, 'aAa' nom, convert(date,'2014-01-14') as dd UNION ALL 
select 2 id, 'bbB' nom, convert(date,'2013-06-13') as dd UNION ALL 
select 4 id, 'dDD' nom, convert(date,'2012-11-05') as dd UNION ALL 
select 6 id, 'FFf' nom, convert(date,'2014-01-12') as dd) T 


SELECT * FROM audit.tmp1 order by 1 
SELECT * FROM audit.tmp2 order by 1 


DECLARE @T TABLE(ID INT); 

MERGE audit.tmp2 WITH (HOLDLOCK) AS T 
USING (SELECT * FROM audit.tmp1 WHERE nom <> 'dd') AS S 
ON (T.id = S.id) 
WHEN NOT MATCHED BY TARGET 
THEN INSERT(id, nom, dd) VALUES(S.id, S.nom, S.dd) 
WHEN MATCHED 
THEN UPDATE SET T.nom = S.nom, T.dd = S.dd 
WHEN NOT MATCHED BY SOURCE 
THEN UPDATE SET T.id = T.id OUTPUT S.id INTO @T; 

DELETE tmp1 
FROM audit.tmp1 
INNER JOIN 
@T AS DEL 
    ON DEL.id = tmp1 .id 


SELECT * FROM audit.tmp1 ORDER BY 1 
SELECT * FROM audit.tmp2 ORDER BY 1 

Espero que esto te ayude.

0

también se puede utilizar a continuación el código

drop table energydata 

create table temp_energydata 
(
webmeterID int, 
DT DateTime , 
kWh varchar(10) 
) 

Insert into temp_energydata 
select 1,getdate()-10, 120 
union 
select 2,getdate()-9, 140 
union 
select 3,getdate()-6, 37 
union 
select 4,getdate()-3, 40 
union 
select 5,getdate()-1, 240 

create table energydata 
(
webmeterID int, 
DT DateTime , 
kWh varchar(10) 
) 

Insert into energydata (webmeterID,kWh) 
select 1, 120 
union 
select 2, 140 
union 
select 3, 37 
union 
select 4, 40 

select * from energydata 
select * from temp_energydata 

begin tran ABC 

DECLARE @T TABLE(ID INT); 

MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target 
USING dbo.temp_energydata AS source 
    ON target.webmeterID = source.webmeterID 
    AND target.kWh = source.kWh 

WHEN MATCHED THEN 
    UPDATE SET target.DT = source.DT 

WHEN NOT MATCHED BY source THEN delete 
OUTPUT source.webmeterID INTO @T; 


DELETE temp_energydata 
WHERE webmeterID in (SELECT webmeterID 
        FROM @T); 
    --INSERT (webmeterID, DT, kWh) 
    --VALUES (source.webmeterID, source.DT, source.kWh) 


rollback tran ABC 
commit tran ABC 
Cuestiones relacionadas