INSERT ou UPDATE table d'une autre table avec key primaire composite

Je cherche la syntaxe correcte et la façon de faire ce qui suit directement à partir de SQL: insert ou mettre à jour (si datatables existent déjà à l'intérieur) TableMain partir des données contenues dans la TableA avec les deux ayant la même key primaire composite.

Les deux tables sont définies comme:

 CREATE TABLE TableA ( [TID0] [int] NOT NULL, [TID1] [int] NOT NULL, [language] [nvarchar](2) NOT NULL, [TID2] [nvarchar](200) NOT NULL, [text] [nvarchar](max) NULL, [updatedOn] [datetime] NOT NULL DEFAULT (getdate()) PRIMARY KEY ( [TID0], [TID1], [language], [TID2], ) ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

TableA sera périodiquement supprimée et remplie.

TableMain comme la même définition, mais contiendra beaucoup plus de lignes de données et ce dont j'ai besoin est d'insert des valeurs jamais vues de TableA dans TableMain , et mettre à jour les lignes déjà existantes.

J'avais l'habitude de faire ce genre d'insertion mais je ne sais pas comment gérer les keys primaires de mise à jour et composites:

 INSERT INTO TableMain SELECT * FROM TableA 

EDIT: j'utilise SQL Server 9.00.5000

EDIT: une autre façon inspirée par MERGE et mime

 DECLARE @updatedIDs TABLE( [TID0] [int], [TID1] [int], [language] [nvarchar](2), [TID2] [nvarchar](200), PRIMARY KEY ([TID0], [TID1], [language], [TID2]) -- as stated by Nikola Markovinović above, thanks ); -- First update records update TableMain set [text] = source.[text], [updatedOn] = source.[updatedOn] OUTPUT inserted.[TID0] inserted.[TID1] inserted.[language] inserted.[TID2] INTO @updatedIDs from TableMain AS main , TableA AS source WHERE TableMain.[TID0] = source.[TID0] and TableMain.[TID1] = source.[TID1] and TableMain.[language] = source.[language] and TableMain.[TID2] = source.[TID2] -- And then insert insert into TableMain select * from TableA AS source where not exists ( select 1 from @updatedIDs AS i where i.[TID0] = source.[TID0] and i.[TID1] = source.[TID1] and i.[language] = source.[language] and i.[TID2] = source.[TID2] ) 

Voici un script que vous pourriez utiliser pour augmenter vos données:

 -- On error transaction is automatically rolled back set xact_abort on begin transaction -- First update records update TableMain set [text] = source.[text], [updatedOn] = source.[updatedOn] from TableMain inner join TableA source on TableMain.[TID0] = source.[TID0] and TableMain.[TID1] = source.[TID1] and TableMain.[language] = source.[language] and TableMain.[TID2] = source.[TID2] -- And then insert insert into TableMain ([TID0], [TID1], [language], [TID2], [text], [updatedOn]) select [TID0], [TID1], [language], [TID2], [text], [updatedOn] from TableA source where not exists ( select * from TableMain where TableMain.[TID0] = source.[TID0] and TableMain.[TID1] = source.[TID1] and TableMain.[language] = source.[language] and TableMain.[TID2] = source.[TID2] ) commit transaction 

Vous pouvez réécrire not exists () comme left join ... where TableMain.TID0 is null si la performance n'est pas satisfaisante.

vous devriez utiliser une déclaration de fusion

quelque chose comme ça:

 merge TableMain AS target using TableA as source ON <join tables here> WHEN MATCHED THEN <update> WHEN NOT MATCHED BY TARGET <Insert> WHEN NOT MATCHED BY SOURCE <delete> 

vous pouvez utiliser la command Merge de SQLServer 2008. Elle vous permet de merge des données d'une autre source de données dans votre source de données principale et de définir un comportement spécifique en cas de correspondance (et vous aimeriez probablement mettre à jour votre table). ne correspond pas et vous aimerez insert le nouvel logging.

http://blog.sqlauthority.com/2010/06/08/sql-server-merge-operations-insert-update-delete-in-single-execution/

vous pouvez visiter ce lien pour get quelques exemples de code.