【问题标题】:SQL, How to loop for a date list using each as parameter for an Procedure?SQL,如何使用每个作为过程的参数来循环日期列表?
【发布时间】:2015-04-29 12:59:09
【问题描述】:

我有一个接收特定日期作为参数的过程 即 Exec ProcDB '20150428'

我经常需要在多个日期运行此过程,并且通常我重新键入 Exec ProcDB 'date1' GO Exec ProcDB 'date2'go..... 我认为它不聪​​明,所以

我可以使用 Select Distinct [dates] From Table1 Order By [dates] 获取有效的日期列表。

所以我想创建一个接收 Start_DtEnd_Dt 的新过程 它会循环我选择的不同返回的所有日期,其中包括 Start_Dt 和 End_Dt。

ie something like:

Create ProcDBlist Start_Dt as date, End_Dt as date
For each date in: Select Distinct [date] from [table1] where [date] >= @Start_Dt and [date] <= @End_dt
Do: Exec ProcDB 'Date n'
End

更新:

最终解决方案:

Create procedure [dbo].[ProcessDBRange] (@Start_dt as varchar(15) =null, @End_dt as varchar(15) =null)
As
Begin
DECLARE @date as varchar(15)

DECLARE Cursor_ProcessDB CURSOR FOR
    Select Distinct Convert(varchar(15), [date], 112) as [date]
    From [Prices]
    Where [date] >= @Start_dt and [date] <= @End_dt
    Order By [date]

OPEN Cursor_ProcessDB

FETCH next FROM Cursor_ProcessDB
INTO @date

WHILE @@FETCH_STATUS = 0

BEGIN

Exec ProcessDB @date

FETCH next FROM Cursor_ProcessDB
INTO @date

END
CLOSE Cursor_ProcessDB
DEALLOCATE Cursor_ProcessDB
End

【问题讨论】:

  • 查看答案here

标签: sql loops stored-procedures sql-server-2014-express


【解决方案1】:

您将需要使用光标。我相信这是一个很好的资源:@​​987654321@

我试着用你提供的信息做一个例子。

DECLARE @Start_dt DATE;
DECLARE @End_dt DATE;
DECLARE @date DATE;

DECLARE cursor_name CURSOR FOR
    SELECT DISTINCT Date
    FROM [table1]
    WHERE Date >= @Start__Dt 
        and Date <= @End__Dt
    ORDER BY Date

OPEN cursor_name

FETCH next FROM cursor_name
INTO @date

WHILE @@FETCH_STATUS = 0

BEGIN

DECLARE @date2 VARCHAR(15)
SET @date2 = (CAST ( @date AS varchar(15) ))

Exec ProcdB date_parameter_name = @date2     

FETCH next FROM cursor_name
INTO @date

END
CLOSE cursor_name
DEALLOCATE cursor_name

【讨论】:

  • 嗨,谢谢。请查看我与该程序相关的问题的另一部分作为原始问题的更新。
  • 如果我理解正确,您是说您使用的 sproc 收到的参数是 varchar,而您的价格表中的 [date] 列是日期时间。如果是这种情况,我建议将 cast 函数放在游标内,以将从 Price 表中提取的数据类型从 Date 更改为 varchar。 technet.microsoft.com/en-us/library/aa224021(v=sql.80).aspx CAST (@date AS VARCHAR(15))
  • 我更新了响应以显示演员的位置,而且我的光标名称不一致(显示为打开子)您需要在您的响应中用您的光标名称替换它
  • 这里有什么问题? Exec ProcessDB @Refdate = (CAST(@date as varchar(15)) ..它说期望选择
  • 抱歉,我自己也在学习一些关于 CAST 的知识。看起来我们不能直接使用强制转换作为参数。我们可以做的是创建另一个等于强制转换值的变量。并将其用于参数。对此感到抱歉,希望这能让你度过难关!你的问题给我带来了一些很好的学习:) 请忽略'@'前面的'。我需要这种格式的评论。 DECLARE '@date2 VARCHAR(15) SET '@date2 = (CAST ('@date AS varchar(15))) Exec ProcdB date_parameter_name = '@date2
【解决方案2】:

这可以通过使用cursor.来完成
基本上是这样的:

DECLARE @Date datetime -- a local variable to get the cursor's result

DECLARE DatesCursor CURSOR FOR
  Select Distinct [dates] where [dates] between @Start_Dt and @End_Dt From Table1 Order By [dates]. -- the query that the cursor iterate on

OPEN DatesCursor
FETCH NEXT FROM DatesCursor INTO @Date 
WHILE @@FETCH_STATUS = 0 -- this will be 0 as long as the cursor returns a result
  BEGIN
    Exec ProcDB @Date
    FETCH NEXT FROM DatesCursor INTO @Date -- don't forget to fetch the next result inside the loop as well!
  END
-- cleanup - Very important!
CLOSE DatesCursor 
DEALLOCATE DatesCursor 

编辑
我刚刚阅读了zimdanen 在 cmets 中给你的link,我必须说我认为在这种情况下它可能比使用光标更好。

编辑#2

首先,将OPEN sub 更改为OPEN cursor_name。 其次,使用CONVERT 以字符串形式获取日期。 确保使用正确的样式进行转换,否则很容易得到错误的日期和/或异常。

【讨论】:

  • 嗨,谢谢。请查看我与该程序相关的问题的另一部分作为原始问题的更新。
  • 子替换。并将 @date 重置为 Date 但 converto 不能以这种方式工作: Exec ProcessDB Convert(varchar(15),@date)
  • @Flib:需要在convert中指定样式;即如果你想转换成dd/MM/yyyy格式你需要写Convert(varchar(10), @date, 103)。您使用的日期格式是什么?
  • 知道了,我需要YYYMMDD,我想它的112。会试试
  • @Flib:是的,那是 112。
【解决方案3】:

你可以用光标来做。您也可以更改 proc 以接收 2 个参数 @sd date, @ed date 然后在 proc 中执行循环:

alter procedure procDB
@sd date,
@ed date
as
begin
    while @sd <= @ed
    begin
        --do your staff

        set @sd = dateadd(dd, 1, @sd)
    end    
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 2021-01-16
    • 2011-04-19
    • 2018-10-07
    • 2016-06-30
    • 1970-01-01
    相关资源
    最近更新 更多