【问题标题】:Loop through a recordset and use the result to do another SQL select and return the results循环遍历记录集并使用结果执行另一个 SQL 选择并返回结果
【发布时间】:2014-09-29 00:57:27
【问题描述】:

我对存储过程完全陌生。这一次,我需要在 MS SQL 中创建一个存储过程。

假设我有下表。

     Table name: ListOfProducts  
      --------------------------
       SomeID, ProductID  

         34, 4
         35, 8
         35, 11

如何传入 SomeID。使用此 SomeID 从表 ListOfProducts 中选择记录集。然后循环遍历这个记录集。

假设我传入 SomeID = 35。

因此,记录集将返回 2 条 SomeID 为 35 的记录。在循环中,我将获得 ProductID 8 和 11,这将用于从另一个表中进行另一个选择。

存储过程应该返回第二次选择的结果。

如何在 MS SQL 存储过程中做到这一点?

对不起,这个新手问题。感谢您的帮助。

【问题讨论】:

  • 我认为这与this question 有关。您能否用您的预期结果更新问题,因为我认为您可能正在寻找JOIN
  • 是的,它与那个问题有关。我正在尝试解决同样的问题。但是,我正在尝试一种不同的方法来解决它。现在,我需要的是能够遍历存储过程中的记录集,并能够从循环内的内部选择返回组合的记录集。
  • 在 SQL 中使用循环的理由很少。通过加入,您几乎总能做得更好。

标签: sql sql-server stored-procedures


【解决方案1】:

如果您想循环浏览记录。你可以这样做:

--Container to Insert Id which are to be iterated
Declare @temp1 Table
(
  tempId int
)
--Container to Insert records in the inner select for final output
Declare @FinalTable  Table
(
  Id int,
  ProductId int
)

Insert into @temp1 
Select Distinct SomeId From YourTable

-- Keep track of @temp1 record processing
Declare @Id int
While((Select Count(*) From @temp1)>0)
Begin
   Set @Id=(Select Top 1 tempId From @temp1)

   Insert Into @FinalTable 
   Select SomeId,ProductId From ListOfProducts Where Id=@Id

   Delete @temp1 Where tempId=@Id
End

Select * From @FinalTable

【讨论】:

  • 如何在while循环中获取SomeId和ProductId的值?你能告诉我一个与价值观有关的声明吗?我不明白要输入什么。 “SomeId”是我可以在 Select SomeId... 行之后使用的神奇变量吗?
【解决方案2】:

如果您不需要对无法在整个集合上执行的产品执行某些操作,那么编写显式循环可能没有意义。 SQL Server 可以自己更好地处理这样的事情。我不知道你的桌子是什么样子的,但你应该试试看起来更像这样的东西。

CREATE PROC dbo.yourProcName 
   @SomeID int
AS 
BEGIN
    SELECT
        P.ProductId,
        P.ProductName
    FROM
        Product P
        JOIN 
            ListOfProducts LOP
            ON LOP.ProductId = P.ProductId
    WHERE
        LOP.SomeId = @SomeID 
END

【讨论】:

    【解决方案3】:

    我必须做类似的事情才能从选择的结果集开始/结束时间中提取小时数,然后创建一个每小时迭代的新表。

    DECLARE @tCalendar TABLE
    (
        RequestedFor VARCHAR(50),
        MeetingType VARCHAR(50),
        RoomName VARCHAR(MAX),
        StartTime DATETIME,
        EndTime DATETIME
    )
    
    INSERT INTO @tCalendar(RequestedFor,MeetingType,RoomName,StartTime,EndTime)
    SELECT req as requestedfor
          ,meet as meetingtype
          ,room as rooms
          ,start as starttime
          ,end as endtime
    
          --,u.datetime2 as endtime
        FROM mytable
    
    
    
            DECLARE @tCalendarHours TABLE
        (
            RequestedFor VARCHAR(50),
            MeetingType VARCHAR(50),
            RoomName VARCHAR(50),
            Hour INT
            )
    
        DECLARE @StartHour INT,@EndHour INT, @StartTime DATETIME, @EndTime DATETIME
        WHILE ((SELECT COUNT(*) FROM @tCalendar) > 0)   
        BEGIN
            SET @StartTime = (SELECT TOP 1 StartTime FROM @tCalendar)
            SET @EndTime = (SELECT TOP 1 EndTime FROM @tCalendar)
            SET @StartHour = (SELECT TOP 1 DATEPART(HOUR,DATEADD(HOUR,0,StartTime)) FROM @tCalendar)
            SET @EndHour = (SELECT TOP 1 DATEPART(HOUR,DATEADD(HOUR,0,EndTime)) FROM @tCalendar)
            WHILE @StartHour <= @EndHour
            BEGIN
                INSERT INTO @tCalendarHours
                SELECT RequestedFor,MeetingType,RoomName,@StartHour FROM @tCalendar WHERE StartTime = @StartTime AND EndTime = @EndTime
                SET @StartHour = @StartHour + 1
            END
            DELETE @tCalendar WHERE StartTime = @StartTime AND EndTime = @EndTime
        END
    

    【讨论】:

      【解决方案4】:

      做这样的事情:

      Declare @ID int
      
      SET @ID = 35
      
      SELECT
         p.SomeID
        ,p.ProductID
       FROM ListOfProducts p
        WHERE p.SomeID = @ID
       -----------------------
         --Or if you have to join to get it
        Declare @ID int
      
        SET @ID = 35
      
          SELECT
            c.SomeID
            ,p.ProductID
            ,p.ProductName
      
          FROM ListOfProducts p
          INNER JOIN categories c on p.ProductID = c.SomeID
          WHERE p.SomeID = @ID
      

      【讨论】:

        【解决方案5】:

        您可以使用带有WHILE 循环和BREAK/CONTINUE 关键字的选项

        CREATE PROC dbo.yourProcName
        @SomeID int
        AS
        BEGIN
          IF OBJECT_ID('tempdb.dbo.#resultTable') IS NOT NULL DROP TABLE dbo.#resultTable
          CREATE TABLE dbo.#resultTable
           (Col1 int, Col2 int)  
          DECLARE @ProductID int = 0
          WHILE(1=1)
            BEGIN
              SELECT @ProductID = MIN(ProductID) 
              FROM ListOfProducts 
              WHERE SomeID = @SomeID AND ProductID > @ProductID
        
              IF @ProductID IS NULL
              BREAK
              ELSE
        
              INSERT dbo.#resultTable
              SELECT Col1, Col2
              FROM dbo.yourSearchTable
              WHERE ProductID = @ProductID
        
              CONTINUE      
            END
          SELECT *
          FROM dbo.#resultTable 
        END    
        

        SQLFiddle上的演示

        【讨论】:

          猜你喜欢
          • 2022-01-08
          • 1970-01-01
          • 2019-02-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多