2009-02-26 8 views
2

J'ai une table qui stocke les informations sur les médicaments du formulaire et qui doit être mise à jour quotidiennement à partir d'un formulaire central. La table temporaire est identique à la table de médicaments. Les données de la table temporaire peuvent être identiques (et la plupart du temps le seront) à la table principale ou peuvent contenir des lignes mises à jour ou de nouvelles lignes.Mise à jour d'une table à partir d'une table temporaire

J'ai une procédure stockée pour mettre à jour la table principale, mais elle échoue car elle ne mettra pas à jour les lignes NULL (s'il y a une nouvelle ligne dans la table temporaire).

C'est un MSSQL Server 2005.

Où suis-je qui ne va pas ici:

-- Insert statements for procedure here 
UPDATE [RX_Billing].[dbo].[FS_Drug] 
SET [TRADENAME] = [RX_Billing].[dbo].[FS_Drug_TEMP].[TRADENAME] 
    ,[CDM] = [RX_Billing].[dbo].[FS_Drug_TEMP].[CDM] 
    ,[NDC] = [RX_Billing].[dbo].[FS_Drug_TEMP].[NDC] 
    ,[IP_COST] = [RX_Billing].[dbo].[FS_Drug_TEMP].[IP_COST] 
    ,[OP_COST] = [RX_Billing].[dbo].[FS_Drug_TEMP].[OP_COST] 
    ,[HH_COST] = [RX_Billing].[dbo].[FS_Drug_TEMP].[HH_COST] 
    ,[VAR_COST] = [RX_Billing].[dbo].[FS_Drug_TEMP].[VAR_COST] 
    ,[LSTUPDATE] = [RX_Billing].[dbo].[FS_Drug_TEMP].[LSTUPDATE] 
FROM [RX_Billing].[dbo].[FS_Drug] 
RIGHT OUTER JOIN [RX_Billing].[dbo].[FS_Drug_TEMP] ON 
      [RX_Billing].[dbo].[FS_Drug].[TRADENAME] = 
        [RX_Billing].[dbo].[FS_Drug_TEMP].[TRADENAME] 

EDIT:

Je suis allé avec le code de Rory. Merci, ça fonctionne magnifiquement.

Une note à Orion Edwards: UPSERT/MERGE est exactement ce que je voulais, mais il n'est pas supporté par SQL Server 2005. Apparemment, il était prévu, mais n'a pas fait cette version. Il est disponible dans le serveur 2008. (D'après ce qu'Interwebs m'a dit.)

Répondre

10

manière standard est de faire un UPDATE et INSERT:

-- UPDATE rows using an INNER JOIN with matching TRADENAME. No need to update TRADENAME column. 
UPDATE drug 
SET [CDM] = tmp.[CDM] 
    , [NDC] = tmp.[NDC] 
    , [IP_COST] = tmp.[IP_COST] 
    , [OP_COST] = tmp.[OP_COST] 
    , [HH_COST] = tmp.[HH_COST] 
    , [VAR_COST] = tmp.[VAR_COST] 
    , [LSTUPDATE] = tmp.[LSTUPDATE] 
FROM [RX_Billing].[dbo].[FS_Drug] drug 
INNER JOIN [RX_Billing].[dbo].[FS_Drug_TEMP] tmp 
    ON drug.[TRADENAME] = tmp.[TRADENAME] 

-- Insert rows that don't have matching TRADENAME 
INSERT INTO drug 
SELECT 
    tmp.[TRADENAME] 
    , tmp.[CDM] 
    , tmp.[NDC] 
    , tmp.[IP_COST] 
    , tmp.[OP_COST] 
    , tmp.[HH_COST] 
    , tmp.[VAR_COST] 
    , tmp.[LSTUPDATE] 
FROM [RX_Billing].[dbo].[FS_Drug] drug 
RIGHT OUTER JOIN [RX_Billing].[dbo].[FS_Drug_TEMP] tmp 
    ON drug.[TRADENAME] = tmp.[TRADENAME] 
WHERE drug.[TRADENAME] IS NULL 

Vous pouvez également supprimer ou marquer comme supprimé des enregistrements médicaments qui ne sont pas dans tmp plus . Faites-le comme une instruction distincte identique à la mise à jour, mais avec une jointure gauche gauche où tmp.TRADENAME est NULL.

2

Vous ne voulez pas faire un INSERT sur les nouvelles lignes, et un UPDATE sur les lignes existantes? Mettre à jour ceci à une INNER JOIN, et ajouter un INSERT séparé devrait résoudre votre problème si je le comprends correctement.

Questions connexes