2010-11-22 8 views
0

J'ai eu ce scénario suivant,Looping dans Trigger?

Il y a quatre tables PAYS, ÉTAT, VILLE, RUE
Et je le fichier Excel avec les enregistrements des above..possibly 2000 lignes que maintenant.

J'ai utilisé SqlBulkCopy pour importer les données dans une table temporaire, nommons la table IMPORT.

Et j'ai écrit un déclencheur pour l'insertion sur la table d'IMPORTATION qui obtient l'enregistrement inséré et sépare le pays, l'état, la ville, la rue puis les insère à la table respective.

Dans ce déclencheur, je dois effectuer une vérification conditionnelle, par exemple, si le nom COUNTRY est déjà présent, il renvoie le COUNTRY_ID sinon l'insérer et obtenir le nouveau COUNTRY_ID.

Ce qui précède fonctionne si le fichier Excel n'a qu'une seule ligne. Une fois que j'ai mis l'original Excel pour l'importation je l'ai compris l'instruction suivante dans le déclencheur échoue "sélectionnez le pays de INSÉRÉ" parce que sqlbulkcopy fait INSERTED à plus d'un enregistrements.

Tableau Structure

PAYS

  • country_id
  • COUNTRY_NAME

ETAT

  • state_id
  • country_id
  • STATE_NAME

CITY

  • CITY_ID
  • state_id
  • country_id
  • CITY_NAME

STREET

  • Street_ID
  • CITY_ID
  • state_id
  • country_id
  • STREET_NAME

IMPORT

  • country_name
  • STATE_NAME
  • CITY_NAME
  • STREET_NAME

Donc je peux avoir énoncé de boucle déclencheur qui fera une boucle à travers tous les enregistrements INSÉRÉ?

Ou comment y remédier de la meilleure façon?

REMARQUE: Comme ils l'utilisent déjà, je n'ai aucun contrôle sur ces structures de table et leurs relations.

Merci d'avance.

Répondre

2

Votre première question est que vous ne devriez jamais considérer en boucle un ensemble d'enregistrements comme un premier choix. C'est presque toujours le mauvais choix car c'est ici. Votre prochain problème est que les triggers traitent l'ensemble des enregistrements pas un à la fois et à partir de votre description, je parie que vous l'avez écrit en supposant qu'il traiterait un enregistrement à la fois. Vous avez besoin d'un processus basé sur un ensemble.

Vous devriez avoir besoin quelque chose comme ceci dans votre déclencheur qui insérerait tous les pays inséré qui ne sont pas déjà dans la table des pays (cela suppose country_id est une colonne identitiy entier):

Insert country (country_name) 
select country_name 
from inserted i 
where not exists 
    (select * from country c 
    where c.country_name = i.country_name) 

Vous pouvez également utiliser un proc stocké au lieu d'un trigger pour insérer dans les vraies tables à partir de la table de transfert.

+0

Désolé pour la réponse tardive .. C'était ce que je cherchais. Merci de m'avoir répondu et éduqué. – vijay

1

Je voudrais jamais mettre une telle tâche de traitement intensif dans un déclencheur sur une table utilisée pour la charge en bloc! Et jamais jamais commencer à mettre des boucles comme des curseurs et des trucs comme ça dans un déclencheur - un déclencheur doit être petit, maigre et méchant - juste un INSERT rapide dans une table d'audit ou quelque chose - mais pas pas lourd!

Ce que vous devez faire est la suivante:

  • utilisation SqlBulkLoad pour obtenir vos données dans cette table de mise en scène aussi rapidement que possible, aucun déclencheur ou quoi que ce soit
  • puis basé sur cette table de mise en scène, faire le post-traitement nécessaire en divisant les valeurs des colonnes et des trucs comme ça

Sinon, vous êtes tout à fait tuer tout avantage que SqlBulkLoad a ..

Et pour faire ce post-traitement (comme la détermination Country_ID pour un donné Country), vous n'avez pas besoin de curseurs ou de l'un de ces bits maléfiques - il suffit d'utiliser standard, UPDATE instructions ordinaires sur votre table - C'est tout ce dont tu as besoin.