首页 > 解决方案 > 存储过程重复插入相同的记录,而不是从 SELECT 循环遍历列表

问题描述

我在编写程序方面相当新(超出基础)

我正在尝试编写一个存储过程,该过程dbo.billing_batch基于循环遍历结果列表 () 的 select 语句插入表 ( @DealerID FROM dbo.vehicle_info)。

SELECT DISTINCT...语句本身可以完美运行,并返回包含 54 条记录的列表。

语句的结果SELECT是动态的,每周都会变化,所以我不能每次都指望 54 条记录。

我正在尝试使用WHILE @DealerID IS NOT NULL循环来执行INSERT例程。

该循环应该是 update dbo.billing_batch,但是它BillingBatchRosterID, DealerID一遍又一遍地插入相同的第一条记录 ( ) 到无穷大。

我知道我一定做错了什么(我从未编写过循环的存储过程)。

任何帮助将不胜感激!

这是存储过程代码:

ALTER PROCEDURE [dbo].[sp_billing_batch_set]
    @varBillingBatchRosterID int
AS 
    SET NOCOUNT ON;
BEGIN
    DECLARE @DealerID int

    SELECT DISTINCT @DealerID = vi.DealerID
    FROM dbo.vehicle_info vi
    LEFT JOIN dbo.dealer_info di ON di.DealerID = vi.DealerID
    WHERE di.DealerActive = 1 
      AND (vi.ItemStatusID < 4 OR vi.ItemStatusID = 5 OR vi.ItemStatusID = 8)
END
 
WHILE @DealerID IS NOT NULL
BEGIN TRY
    INSERT INTO dbo.billing_batch (BillingBatchRosterID, DealerID)
    VALUES(@varBillingBatchRosterID,    -- BillingBatchRosterID - int
           @DealerID)                   -- DealerID - int
END TRY
BEGIN CATCH
    SELECT  ' There was an error: '  + error_message() AS ErrorDescription
END CATCH

标签: sql-serverloopsstored-procedureswhile-loopinsert

解决方案


您在这里遇到与最近的另一篇文章相同的问题:Iterate over a table with a non-int id value

  1. 为什么要做一个循环?只需将其作为单个 SQL 语句执行
  2. 如果您必须使用循环,则需要在每次运行时更新您的 @Dealer 值(例如,更新到下一个 DealerId),否则它将无限循环使用相同的 DealerID 值
  3. 不要循环。

这是一个不需要循环的示例。

ALTER PROCEDURE [dbo].[P_billing_batch_set]
    @varBillingBatchRosterID int
AS 
BEGIN
SET NOCOUNT ON;

BEGIN TRY

INSERT INTO dbo.billing_batch (DealerID, BillingBatchRosterID)
    SELECT DISTINCT vi.DealerID, @varBillingBatchRosterID
    FROM dbo.vehicle_info vi
        INNER JOIN dbo.dealer_info di ON di.DealerID = vi.DealerID
    WHERE di.DealerActive = 1 
        AND (vi.ItemStatusID < 4 
            OR vi.ItemStatusID = 5
            OR vi.ItemStatusID = 8
            );

END TRY
BEGIN CATCH
    SELECT  ' There was an error: '  + error_message() AS ErrorDescription;
END CATCH;

END;

注一

  • 将 LEFT JOIN 更改为 INNER JOIN,因为您的 WHERE 子句需要该记录存在于 Dealer_info 表中
  • SET NOCOUNT ON;移到 BEGIN-END 部分内
  • 移到END最后
  • 根据@marc_s 的出色评论重命名您的存储过程(关于问题本身)

推荐阅读