【问题标题】:Inserting weekends into SQL Server table将周末插入 SQL Server 表
【发布时间】:2016-12-02 12:11:12
【问题描述】:

我正在尝试使用以下存储过程将日期、dayName 等年度周末详细信息插入到 SQL Server 表中

alter procedure usp_AddOfficeHolidays
    @paramName NVARCHAR(max)
as
begin
    DECLARE @Year AS INT,
            @FirstDateOfYear DATETIME,
            @LastDateOfYear DATETIME

    -- You can change @year to any year you desire
    SELECT @year = 2016

    SELECT @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0)
    SELECT @LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0)

    -- Creating Query to Prepare Year Data
    --declare dayN varchar(max)
    if (select COUNT(*) from tblWeekSettings) < 1
    begin
        ;WITH cte AS 
        (
            SELECT 
                1 AS DayID,
                @FirstDateOfYear AS FromDate,
                DATENAME(dw, @FirstDateOfYear) AS Dayname
            UNION ALL
            SELECT 
                cte.DayID + 1 AS DayID,
                DATEADD(d, 1 ,cte.FromDate),
                DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname
            FROM cte
            WHERE DATEADD(d, 1, cte.FromDate) < @LastDateOfYear
        )
        SELECT FromDate AS Date, Dayname
        FROM CTE
        WHERE DayName IN (SELECT Param FROM dbo.fn_MVParam(@paramName,','))
        OPTION (MaxRecursion 370)
    end
    else
    begin
        Select 'Exists'
    end
end

并使用

执行它
exec usp_AddOfficeHolidays 'Saturday,Sunday'

返回以下结果

这很好用,但是我无法将这些详细信息添加/插入到下表中

当我尝试通过别名 CTE

访问 WEEKEND 详细信息时遇到以下错误

语句终止。最大递归100已用完 在语句完成之前

虽然我已经添加了子句

 OPTION (MaxRecursion 370)

我在堆栈溢出时发现的这些链接建议

编辑

当我尝试这样的事情时,基本上我会遇到指定的错误

alter procedure usp_AddOfficeHolidays
@paramName NVARCHAR(max)
as
begin
----------------------------------------------------------
DECLARE @Year AS INT,
@FirstDateOfYear DATETIME,
@LastDateOfYear DATETIME
-- You can change @year to any year you desire
SELECT @year = 2016
SELECT @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0)
SELECT @LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0)
-- Creating Query to Prepare Year Data
--declare dayN varchar(max)
if (select COUNT(*) from tblWeekSettings) < 1

    begin
        ;WITH cte AS (
        SELECT 1 AS DayID,
        @FirstDateOfYear AS FromDate,
        DATENAME(dw, @FirstDateOfYear) AS Dayname
        UNION ALL
        SELECT cte.DayID + 1 AS DayID,
        DATEADD(d, 1 ,cte.FromDate),
        DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname
        FROM cte
        WHERE DATEADD(d,1,cte.FromDate) < @LastDateOfYear
        )



        SELECT FromDate AS Date, Dayname
        FROM CTE
        WHERE DayName IN(SELECT Param FROM dbo.fn_MVParam(@paramName,','))

        insert into tblWeekSettings(DayNo,WeekDayName,Dates)
        values('',Dayname,Date)

        OPTION (MaxRecursion 370)
    end

else
    begin
        Select 'Exists'
    end


--select cte
-----------------------------------------------------------
end

我们将不胜感激任何形式的帮助!我只需要在我指定的表中插入数据!

谢谢!

【问题讨论】:

  • if (select COUNT(*) from tblWeekSettings) &lt; 1 -> if not exists(select 1 from tbl...)
  • 显示带有 sp 名称、行号等的完整错误消息。
  • @ivanStarostin 这个存储过程工作得很好,我只需要将数据插入到我在问题中提到的表中!
  • 这是一个练习吗?如果不是,为什么要使用递归而不是利用一周有 7 天的事实?您可以从一年中的第一个周末开始循环 52-53 次,每个循环增加 7 天。
  • @AimalKhan “当我尝试通过别名 CTE 访问 WEEKEND 详细信息时遇到以下错误” - 显示包含 sp 名称、行号等的完整错误消息.你得到一个例外,不是吗?无需任何编辑即可显示该异常。

标签: sql sql-server stored-procedures recursion


【解决方案1】:

这是错误:

    SELECT FromDate AS Date, Dayname
    FROM CTE
    WHERE DayName IN(SELECT Param FROM dbo.fn_MVParam(@paramName,','))

我拆分这段代码是为了让您了解在这种情况下实际运行的代码:

    insert into tblWeekSettings(DayNo,WeekDayName,Dates)
    values('',Dayname,Date)
    OPTION (MaxRecursion 370)

OPTION (MAX RECURSION) 现在属于单个插入语句。这是独立的,与 CTE 完全无关。

我想你实际上需要这个:

    ;with CTE (...)
    insert into tblWeekSettings(DayNo,WeekDayName,Dates)
    SELECT FromDate AS Date, Dayname
    FROM CTE
    WHERE DayName IN(SELECT Param FROM dbo.fn_MVParam(@paramName,','))
    OPTION (MaxRecursion 370)

但目标表中有三列,而您的选择只有两列。所以你必须更新你的选择。

关于INSERT-SELECT的一些提示:
http://www.w3schools.com/sql/sql_insert_into_select.asp

这段代码:

    insert into tblWeekSettings(DayNo,WeekDayName,Dates)
    values('',Dayname,Date)

没有任何插入源。这不是有效的代码 - 您在这里没有任何 Dayname,Date 变量 - 它们甚至没有被 @ 作为变量引用。这完全不是有效的代码。

【讨论】:

  • 您希望如何将 VALUES 输入 tblWeekSettings?只是好奇!
  • 这就是INSERT...SELECT 语句的作用。
  • @AimalKhan 如果它是正确的,你应该接受这个答案。
  • 谢谢@ivanStarostin。你的建议奏效了:D
【解决方案2】:

对于遇到以下问题的人

  • 获取 Weeked 详细信息,例如 DayName、Date
  • 插入表格

这个存储过程可以解决问题。

alter procedure usp_AddOfficeHolidays
@paramName NVARCHAR(max)
as
begin
----------------------------------------------------------
DECLARE @Year AS INT,
@FirstDateOfYear DATETIME,
@LastDateOfYear DATETIME
-- You can change @year to any year you desire
SELECT @year = 2016
SELECT @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0)
SELECT @LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0)
-- Creating Query to Prepare Year Data
--declare dayN varchar(max)
if (select COUNT(*) from tblWeekSettings) < 1

    begin
        ;WITH cte AS (
        SELECT 1 AS DayID,
        @FirstDateOfYear AS FromDate,
        DATENAME(dw, @FirstDateOfYear) AS Dayname
        UNION ALL
        SELECT cte.DayID + 1 AS DayID,
        DATEADD(d, 1 ,cte.FromDate),
        DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname
        FROM cte
        WHERE DATEADD(d,1,cte.FromDate) < @LastDateOfYear
        )


        insert into tblWeekSettings(DayNo,Dates,WeekDayName) 
        SELECT '',FromDate AS Date, Dayname
        FROM CTE WHERE DayName IN(SELECT Param FROM dbo.fn_MVParam(@paramName,',')) 

        OPTION (MaxRecursion 30000) 




    end

else
    begin
        Select 'Exists'
    end


--select cte
-----------------------------------------------------------
end

另外,这篇文章真的很有帮助。

【讨论】:

    【解决方案3】:

    试试这个,希望对你有用。

    alter procedure usp_AddOfficeHolidays
    @paramName NVARCHAR(max)
    as
    begin
    ----------------------------------------------------------
    DECLARE @Year AS INT,@DayNo as int=1,
    @FirstDateOfYear DATETIME,
    @LastDateOfYear DATETIME
    -- You can change @year to any year you desire
    SELECT @year = 2016
    SELECT @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0)
    SELECT @LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0)
    Select getdate() DateOfYear into #tbl where 1=0
    -- Creating Query to Prepare Year Data
    --declare dayN varchar(max)
    if (select COUNT(*) from tblWeekSettings) < 1
    
        begin
                while (@FirstDateOfYear< @LastDateOfYear)
                begin
                    Insert Into #tbl (DayNo,DateOfYear) values (@DayNo,@FirstDateOfYear)
                    set @FirstDateOfYear+=1
                    set @DayNo+=1;
                End
    
                Insert Into tblWeekSettings (DayNo,WeekDayName,Dates)
                SELECT DayNo,DATENAME(dw, DateOfYear) Name,DateOfYear AS Date
                FROM #tbl
                WHERE DATENAME(dw, DateOfYear) IN(SELECT Param FROM dbo.fn_MVParam(@paramName,','))
    
        end
    
    else
        begin
            Select 'Exists'
        end
    
    
    --select cte
    -----------------------------------------------------------
    end
    

    【讨论】:

    • 感谢您的评论@m.jamshaidAlam 但我得到了答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    相关资源
    最近更新 更多