【问题标题】:Looping through SQL Server table, running stored procedure for the row, and put results in to a table循环遍历 SQL Server 表,为行运行存储过程,并将结果放入表中
【发布时间】:2016-01-30 18:49:52
【问题描述】:

我有一个 SQL Server 存储过程,用于获取员工几天内的计时工时。该过程使用卡代码值来获取有关员工的信息。

我想做的是从一个表中选择所有CardCodes,然后遍历运行存储过程的每条记录,然后用每个记录的结果制作一个表。所以到最后会有一张桌子,每个员工的工作时间。

获取CardCodes列表的查询:

SELECT     
    CardCode
FROM
    CHINA_VISION_PubCards

生成一个这样的列表。

007b7aaf
00cf77b6
00cf9200
00cf9f40
007B6FFB
00d398dd
00cf4673

等等。

我可以像这样在 SQL Server 中运行存储过程。

EXEC [dbo].[getPast5DaysWorkedHours] @CardCode = N'007da097'

007da097 是员工的卡号。

这会产生如下结果:

Employee Name | CardCode  |  Clock No  | Date   |  Seconds |  Time  
     Name       007da097      005718    2015.10.16  28761   07:59:21
     Name       007da097      005718    2015.10.21  28991   08:03:11
     Name       007da097      005718    2015.10.23  29768   08:16:08
     Name       007da097      005718    2015.10.28  29441   08:10:41

重申我正在尝试做的事情:我想遍历卡代码列表,并为每个卡代码运行带有 cardCode 值的存储过程。然后将每个过程调用的结果放入一个表中。

【问题讨论】:

  • 最好将您的存储过程更改为期望 @CardCode 作为 TVP(table valued parameter) 并允许多个输入。使用循环是非常低效的
  • 查看链接中的演示。非常容易创建类型,更改过程以允许 TVP,稍微更改逻辑,填充参数并调用 sp :)
  • 但是,要执行您的要求,您将使用光标。 Google SQL CURSOR 有大量示例。
  • 但实际上不要使用游标。没必要。
  • 你能选择一个正确的答案吗?

标签: sql-server tsql stored-procedures sql-server-2008-r2


【解决方案1】:

SQL 有 while 循环

While Loop T-SQL

你可以这样做。 (未经测试)

IF OBJECT_ID('TempDB..#TEMP') IS NOT NULL DROP TABLE #TEMP
SELECT  distinct  CardCode
INTO #TEMP
FROM CHINA_VISION_PubCards

WHILE ( (select count(*) FROM #TEMP) > 0 )
    BEGIN
         DECLARE @CardCode varchar(50)
         SELECT TOP 1 @CardCode=CardCode FROM #TEMP

         INSERT INTO TableTarget
         EXEC [dbo].[getPast5DaysWorkedHours] @CardCode

         DELETE FROM #TEMP WHERE CardCode = @CardCode
    END

【讨论】:

    【解决方案2】:

    您可以使用 WHILE 循环遍历每个条目,而无需使用光标或重复 SELECT 和 DELETE:

    DECLARE @store table (id bigint identity(1,1), CardCode (your cardcode column type here))
    
    insert into @store (CardCode)
    SELECT DISTINCT     
        CardCode
    FROM
        CHINA_VISION_PubCards
    
    declare @idx bigint = 1
    declare @max bigint = (select MAX(id) from @store)
    
    WHILE @idx<=@max
    BEGIN
    EXEC [dbo].[getPast5DaysWorkedHours] @CardCode = (select top 1 CardCode from @store where id = @idx)
    
    set @idx = @idx+1
    
    END
    

    不过,cmets 是对的 - 如果您可以使用表值参数来传递一组值,那就更好了。

    【讨论】:

      猜你喜欢
      • 2023-01-11
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多