首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >存储过程中的sql2000循环

存储过程中的sql2000循环
EN

Stack Overflow用户
提问于 2009-03-03 18:01:11
回答 2查看 874关注 0票数 2

我对SQL非常陌生,我可以相当容易地使用基本语句,但我还没有弄清楚循环。

代码语言:javascript
复制
Foreach(JobHeaderID AS @OldJobHeaderID in dbo.EstimateJobHeader WHERE EstimateID=@OldEstimateID)  
{  
  INSERT EstimateJobHeader (ServiceID,EstimateID) 
  SELECT ServiceID, @NewEstimateID 
  FROM EstimateJobHeader 
  WHERE EstimateID=@OldEstimateID;  

  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 JobHeaderID=@OldJobHeaderID

  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 JobHeaderID=@OldJobHeaderID  

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

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-03-03 18:09:09

应避免在存储过程中出现循环。

Sql是一种声明性语言,而不是您最常用的命令式语言。几乎所有你想对循环做的事情都应该作为基于集合的操作来完成,或者在客户端代码中完成。当然,也有例外,但并不像你想的那么多。

请看以下内容:

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

您问过如何使用基于集合的方法来实现这一点。我会尽我最大的努力,但是你的代码早期有一个bug,这使得我很难确保我读对了它。第一个INSERT语句中的条件与FOREACH循环中的条件相匹配。因此,要么循环只运行一次(在那里返回一条记录),要么insert在每次迭代中插入几条新记录(是的,insert语句可以一次添加多条记录)。如果它添加了几条记录,为什么只获得最后一次插入时创建的标识?

也就是说,我想我理解得足够好了,可以给你看一些东西了。看起来你只是在复制一个估计值。您也不需要解释@NewEstimateID值从何而来。如果有父表,那么就这么做,但了解一下会很有帮助。

代码语言:javascript
复制
/* 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

上面的代码假设ServiceID+EstimateID在EstimateJobHeader表中是唯一的。如果不是这样,我需要知道表中哪些列或哪些列唯一地标识表中的行,这样我就可以将旧记录与新记录连接起来,并确保关系是1:1。

最后,为了简洁起见,省略了错误检查。

票数 6
EN

Stack Overflow用户

发布于 2009-03-03 18:03:17

看一下WHILE语句:

http://msdn.microsoft.com/en-us/library/aa260676(SQL.80).aspx

然而,根据你正在尝试做的事情,可能有一种更好的、基于集合的方法来做你想做的事情,并且应该首先考虑这一点。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/607456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档