gpt4 book ai didi

存储过程中的sql2000循环

转载 作者:行者123 更新时间:2023-12-04 22:34:33 24 4
gpt4 key购买 nike

我是 SQL 的新手,我可以相当轻松地使用基本语句,但我还没有弄清楚循环。

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
}

最佳答案

您应该避免存储过程中的循环。

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

看这个:
Why is it so difficult to do a loop in T-SQL


您询问了如何使用基于集合的方法来做到这一点。我会尽力而为,但您的代码早期存在一个错误,因此很难确定我是否正确阅读了它。第一个 INSERT 语句的条件与 FOREACH 循环的条件匹配。因此,循环只会运行一次(那里返回一条记录),或者您的插入每次迭代都会插入几条新记录(是的,插入语句可以一次添加多条记录)。如果它要添加多条记录,为什么您只获得最后一次插入创建的标识?

也就是说,我想我已经足够了解它了,可以向您展示一些东西。看来您只是在复制估算值。您也没有解释 @NewEstimateID 值的来源。如果有父表,那就这样吧,但了解它会很有帮助。

/* 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。

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

关于存储过程中的sql2000循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/607456/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com