简体   繁体   中英

SQL Server - How to bring back and the result of a WHILE BREAK Loop in a function?

I have this bit of code which works

DECLARE @IntDte as INT
SET @IntDte = 1
WHILE @IntDte <=10
BEGIN
IF (SELECT isworkday FROM Calendar WHERE date=CAST(FLOOR(CAST(GETDATE()-@IntDte As float))As datetime))= 1 -- 1 is a workday 0 is a weekend
            BREAK
            ELSE
        SET @IntDte= @IntDte + 1        
END
PRINT @IntDte

This brings back the last an integer that will bring back the last working day (ie if it is Monday today the loop will bring back 4 because that's Friday.

What I want though which I'm struggling is to build this into a function to get the date. I have this so far but its not correct -

Create FUNCTION [dbo].[PREVIOUSWORKINGDAY]
RETURNS datetime
AS BEGIN
DECLARE @PWD as datetime

SET @PWD = GetDate() -
(DECLARE @IntDte as INT
SET @IntDte = 2
WHILE @IntDte <=10
BEGIN
IF (SELECT isworkday FROM Calendar WHERE date=CAST(FLOOR(CAST(GETDATE()-@IntDte As float))As datetime))= 1 -- 1 is a workday 0 is a weekend
            BREAK
            ELSE
        SET @IntDte= @IntDte + 1        
END
RETURN)

RETURN @PWD
END

Would anyone be able to point out where im going wrong, at current im getting syntax errors -

Msg 102, Level 15, State 1, Procedure PREVIOUSWORKINGDAY, Line 2 Incorrect syntax near 'RETURNS'.

Msg 156, Level 15, State 1, Procedure PREVIOUSWORKINGDAY, Line 7 Incorrect syntax near the keyword 'DECLARE'.

Msg 102, Level 15, State 1, Procedure PREVIOUSWORKINGDAY, Line 16 Incorrect syntax near ')'.

Msg 178, Level 15, State 1, Procedure PREVIOUSWORKINGDAY, Line 18 A RETURN statement with a return value cannot be used in this context.

Im assuming I have some stuff in the wrong place but not sure where it should go.

thanks

The problem with your SQL looks to be that you have two return statements and you are trying to embed declare statements. Here is how I'd re-write your version:

Create FUNCTION [dbo].[PREVIOUSWORKINGDAY]
RETURNS datetime
AS BEGIN
    DECLARE @PWD as datetime
    DECLARE @IntDte as INT

    SET @IntDte = 2
    WHILE @IntDte <=10
    BEGIN
        IF (SELECT isworkday FROM Calendar WHERE date=CAST(FLOOR(CAST(GETDATE()-@IntDte As float))As datetime))= 1 -- 1 is a workday 0 is a weekend
            BREAK
        ELSE
            SET @IntDte= @IntDte + 1        
    END

    SET @PWD = GetDate() - IntDte

    RETURN @PWD
END

This is how I would write it though.

Create FUNCTION [dbo].[PREVIOUSWORKINGDAY]
RETURNS datetime
AS BEGIN
    DECLARE @PWD as datetime

        SELECT @PWD=Max(date)
        FROM Calendar
        WHERE isworkday=1
        AND date<CONVERT(DATE,GETDATE())

    RETURN @PWD
END

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM