2009-03-03 6 views
2

Je suis très nouveau à SQL je peux travailler avec des instructions de base assez facilement, mais je n'ai pas encore compris boucles.sql2000 boucle dans une procédure stockée

Foreach(JobHeaderID AS @OldJobHeaderID in dbo.EstimateJobHeader WHERE [email protected]) 
{ 
    INSERT EstimateJobHeader (ServiceID,EstimateID) 
    SELECT ServiceID, @NewEstimateID 
    FROM EstimateJobHeader 
    WHERE [email protected]; 

    SELECT @err = @@error 
    IF @err <> 0 
    BEGIN 
    ROLLBACK TRANSACTION 
    SET @RETURN_VALUE = 4 
    RETURN 4 
    END 

    SET @NewJobHeaderID = CAST(SCOPE_IDENTITY() AS INT) 

    SELECT @err = @@error 
    IF @err <> 0 
    BEGIN 
    ROLLBACK TRANSACTION 
    SET @RETURN_VALUE = 3 
    RETURN 3 
    END 

    INSERT EstimateDetail (JobHeaderID, OtherCols) 
    SELECT (@NewJobHeaderID,OtherCols) 
    FROM EstimateDetail 
    WHERE [email protected] 

    SELECT @err = @@error 
    IF @err <> 0 
    BEGIN 
    ROLLBACK TRANSACTION 
    SET @RETURN_VALUE = 3 
    RETURN 3 
    END 

    INSERT EstimateJobDetail (JobHeaderID, OtherCols) 
    SELECT (@NewJobHeaderID, OtherCols) 
    FROM EstimateJobDetail 
    WHERE [email protected] 

    SELECT @err = @@error 
    IF @err <> 0 
    BEGIN 
    ROLLBACK TRANSACTION 
    SET @RETURN_VALUE = 3 
    RETURN 3 
    END 
} 
+0

Mis à jour ma réponse: poster ici afin que vous soyez ping sur votre page d'utilisateur. –

Répondre

6

Vous devez éviter les boucles dans les procédures stockées. Sql est un langage déclaratif, plutôt que les langages impératifs auxquels vous êtes le plus habitué. Presque tout ce que vous voulez faire avec une boucle doit être fait comme une opération basée sur un ensemble ou fait dans le code client. Il y a, bien sûr, des exceptions, mais pas autant que vous le pensez.

Voir ceci:
Why is it so difficult to do a loop in T-SQL


Vous avez demandé comment le faire en utilisant des méthodes basées-set. Je ferai de mon mieux, mais il y a un bogue au début de votre code qui fait qu'il est difficile de s'assurer que je le lis bien. La condition de la première instruction INSERT correspond à la condition de la boucle FOREACH. Ainsi, soit la boucle ne sera exécutée qu'une seule fois (un enregistrement y est retourné), soit votre insert insère plusieurs nouveaux enregistrements par itération (oui, les instructions insert peuvent ajouter plus d'un enregistrement à la fois). Et si vous ajoutez plusieurs enregistrements, pourquoi obtenez-vous seulement l'identité créée par le dernier insert? Cela dit, je pense que je le comprends assez bien pour vous montrer quelque chose. On dirait que vous faites juste une copie d'une estimation. Vous n'expliquez pas non plus d'où provient la valeur @NewEstimateID. S'il y a une table parent, alors il en sera ainsi, mais il serait utile de le savoir.

/* Where'd @NewEstimateID come from? */ 
/* If there are several records in EstimateJobHeader with @OldEstimateID, 
* this will insert one new record for each of them */ 
INSERT EstimateJobHeader (ServiceID,EstimateID) 
    SELECT ServiceID, @NewEstimateID 
    FROM EstimateJobHeader 
    WHERE EstimateID= @OldEstimateID 

/* Copy EstimateDetail records from old estimate to new estimate */ 
INSERT EstimateDetail (JobHeaderID, OtherCols) 
    SELECT (new.JobHeaderID,ed.OtherCols) 
    FROM EstimateJobHeader new 
    INNER JOIN EstimateJobHeader old ON old.EstimateID= @OldEstimateID 
     AND new.EstimateID= @NewEstimateID AND old.ServiceID=new.ServiceID 
    INNER JOIN EstimateDetail ed ON ed.JobHeaderID= old.JobHeaderID 

/* Copy EstimateJobDetail records from old estimate to new estimate */ 
INSERT EstimateJobDetail (JobHeaderID, OtherCols) 
    SELECT (new.JobHeaderID,ed.OtherCols) 
    FROM EstimateJobHeader new 
    INNER JOIN EstimateJobHeader old ON old.EstimateID= @OldEstimateID 
     AND new.EstimateID= @NewEstimateID AND old.ServiceID=new.ServiceID 
    INNER JOIN EstimateJobDetail ejd ON ejd.JobHeaderID= old.JobHeaderID 

Le code fait l'hypothèse ci-dessus le ServiceID + EstimateID est unique dans la table EstimateJobHeader. Si ce n'est pas le cas, j'ai besoin de savoir quelle colonne ou quelles colonnes identifient de façon unique les lignes de la table, afin que je puisse joindre l'ancien enregistrement avec le nouveau et être certain que la relation est 1: 1.

Enfin, la vérification des erreurs a été omise par souci de brièveté.

+0

J'ai posté ce que je suis en train d'accomplir. Comment ferais-je cela dans une opération basée sur un ensemble? –

Questions connexes