存储过程重复插入相同的记录,而不是从 SELECT 循环遍历列表

Stored procedure inserting the same record repeatedly instead of looping through list from SELECT

我在编写程序方面相当陌生(超出基础知识)

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

SELECT DISTINCT... 语句本身非常有效,returns 包含 54 条记录的列表。

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

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

循环应该更新 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

您遇到的问题与另一个最近的 post 相同: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 table
  • SET NOCOUNT ON; 移至 BEGIN-END 部分
  • END移到了最后
  • 根据@marc_s(关于问题本身)的精彩评论重命名了您的存储过程