web-dev-qa-db-fra.com

Qu'est-ce qu'un équivalent "INSERT IGNORE" dans MS SQL Server?

J'essaie d'insérer des enregistrements dans la base de données MySQL à partir d'un serveur MS SQL en utilisant le "OPENQUERY" mais ce que j'essaie de faire est d'ignorer les messages de clés en double. Donc, lorsque la requête s'exécute en double, ignorez-la et continuez.

Quelles idées puis-je faire pour ignorer les doublons?

Voici ce que je fais:

  1. extraire des enregistrements de MySQL en utilisant "OpenQuery" pour définir MySQL "A.record_id"
  2. Joindre ces enregistrements à des enregistrements dans MS SQL Server "avec un critère spécifique et non un identifiant direct" à partir d'ici, je trouve un nouvel identifiant d'enregistrement "B.new_id" dans SQL Server.
  3. Je veux insérer les résultats trouvés dans une nouvelle table dans MySQL comme donc A.record_id, B.new_id Ici, dans la nouvelle table, j'ai A.record_id défini comme clé primaire pour cette table.

Le problème est que lors de la jonction du tableau A au tableau B, je trouve parfois 2+ enregistrements dans le tableau B correspondant aux critères que je recherche, ce qui entraîne la valeur A.record_id à 2+ fois dans mon ensemble de données avant de l'insérer dans le tableau A ce qui cause le problème. Remarque Je peux utiliser la fonction d'agrégation pour éliminer les enregistrements.

18
Jaylen

Je ne pense pas qu'il existe une option spécifique. Mais c'est assez simple à faire:

insert into oldtable(. . .)
    select . . .
    from newtable
    where not exists (select 1 from oldtable where oldtable.id = newtable.id)

S'il existe plusieurs jeux de clés uniques, vous pouvez ajouter des instructions not exists Supplémentaires.

ÉDITER:

Pour le problème révisé:

insert into oldtable(. . .)
    select . . .
    from (select nt.*, row_number() over (partition by id order by (select null)) as seqnum
          from newtable nt
         ) nt
    where seqnum = 1 and
          not exists (select 1 from oldtable where oldtable.id = nt.id);

La fonction row_number() attribue un numéro séquentiel à chaque ligne d'un groupe de lignes. Le groupe est défini par l'instruction partition by. Les nombres commencent à 1 et augmentent à partir de là. La clause order by Indique que vous ne vous souciez pas de la commande. Exactement une ligne avec chaque id aura une valeur de 1. Les lignes en double auront une valeur supérieure à un. Le seqnum = 1 Choisit exactement une ligne par identifiant.

13
Gordon Linoff

Si vous êtes sur SQL Server 2008+, vous pouvez utiliser MERGE pour faire un INSERT si la ligne n'existe pas, ou un UPDATE.

Exemple:

MERGE
INTO    dataValue dv
USING   tmp_holding_DataValue t
ON      t.dateStamp = dv.dateStamp
        AND t.itemId = dv.itemId
WHEN NOT MATCHED THEN
INSERT  (dateStamp, itemId, value)
VALUES  (dateStamp, itemId, value)
10
Barb C. Goldstein