Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You should avoid loops in stored procedures. </p> <p>Sql is a declarative language, rather than the imperative languages you are most used to. Nearly everything you want to do with a loop should either be done as set-based operation or done in client code. There are, of course, exceptions, but not as many as you think.</p> <p>See this:<br> <a href="https://stackoverflow.com/questions/588050/why-is-it-so-difficult-to-do-a-loop-in-t-sql">Why is it so difficult to do a loop in T-SQL</a></p> <hr> <p>You asked how to do it using set-based methods. I'll do my best, but there's a bug early in your code that makes it hard to be sure I'm reading it right. The condition on the first INSERT statement matches the condition on the FOREACH loop. So either the loop will only ever run once (one record returned there), or your insert is inserting several new records per iteration (yes, insert statements can add more than one record at a time). And if it's adding several records, why do you only get the identity created by the last insert?</p> <p>That said, I think I understand it well enough to show you something. It looks like you're just making a copy of an estimate. You also don't explain where the @NewEstimateID value comes from. If there's a parent table then so be it, but it would be helpful to know about.</p> <pre><code>/* 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 </code></pre> <p>The code above makes the assumption the ServiceID+EstimateID is unique within the EstimateJobHeader table. If this is not the case, I need to know what column or columns do uniquely identify rows in the table, so that I can join the old record with the new and be certain the relationship is 1:1. </p> <p>Finally, error checking was omitted for brevity.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload