SQL Function - Variable setting itself to random value - function

I have created the below function, and it seems to at random to change the #FCST and #QTY values to random selections. Here is an example of the program in debug returning a bad value for #FCST. As #FCST was at 9.53, I expect it to return 9.53.
CREATE FUNCTION dbo.LTBADJ
(#MAT VARCHAR(30),#LCUT DATE, #QS DATE,#STAT FLOAT, #MCA FLOAT)
RETURNS FLOAT
AS BEGIN
DECLARE #HD DATE
DECLARE #ED DATE
DECLARE #FCST FLOAT
DECLARE #QTY FLOAT
DECLARE #YRS FLOAT
SET #ED =
(SELECT TOP 1 [EO_END_DATE] FROM [dbo].[EO_LTB]
WHERE [W_PART_NUMBER] = #MAT
AND [APPROVED_DATE] <= #LCUT
ORDER BY [EO_END_DATE] DESC)
SET #HD =DATEADD(YEAR,2,#QS)
SET #FCST = (CASE WHEN #MCA <= #STAT THEN #MCA ELSE #STAT END)
SET #FCST = (CASE WHEN #FCST <.5 THEN .5 ELSE #FCST END)
SET #YRS = (DATEDIFF(DAY,#HD,#ED) + 730)/365
SET #QTY = #FCST * #YRS
SET #QTY = (CASE WHEN #ED<=#HD THEN 0 ELSE #QTY END)
RETURN #QTY
END ;
EDIT: Example of #QTY incorrectly calculated

All seems correct - you can see what's going on by running the below SQL.
I suspect the confusion's the e-002 and e-001 on the end of the numbers; that's just SQL trying to display the values of floats; because of how floating point arithmetic works, some numbers are calculated slightly out from what you'd expect, then to try to make them readable SQL will display the numbers with an exponent.
declare #MAT VARCHAR(30) = '50309120000W'
,#LCUT DATE = '2014-10-26'
, #QS DATE = '2014-10-27'
,#STAT FLOAT = 9.5399999999999999e-002
, #MCA FLOAT = 9.5399999999999999e-002
DECLARE #HD DATE
DECLARE #ED DATE
DECLARE #FCST FLOAT
DECLARE #QTY FLOAT
DECLARE #YRS FLOAT
SET #ED =
(
SELECT TOP 1 [EO_END_DATE]
FROM (SELECT '2019-02-28' [EO_END_DATE], #MAT [W_PART_NUMBER], #LCUT [APPROVED_DATE] ) X
WHERE [W_PART_NUMBER] = #MAT
AND [APPROVED_DATE] <= #LCUT
ORDER BY [EO_END_DATE] DESC
)
SET #HD =DATEADD(YEAR,2,#QS)
SET #FCST = (CASE WHEN #MCA <= #STAT THEN #MCA ELSE #STAT END)
SELECT #FCST
SET #FCST = (CASE WHEN #FCST <.5 THEN .5 ELSE #FCST END)
SELECT #FCST
SET #YRS = (DATEDIFF(DAY,#HD,#ED) + 730)/365
SET #QTY = #FCST * #YRS
SELECT #FCST, #YRS, #QTY
SET #QTY = (CASE WHEN #ED<=#HD THEN 0 ELSE #QTY END)
SELECT #QTY, #ED, #HD

Related

MySql cursor return first row

I been work in a procedure with MySql to get an overall of sales of all offices in a date range gives by the user using a cursor, but only return the first office in the table.
Here's the table with offices:
SELECT DISTINCT
(num_suc_bsale)
FROM
documentos_historico
WHERE
num_suc_bsale IS NOT NULL
ORDER BY num_suc_bsale ASC
# num_suc_bsale
1
2
3
4
5
6
7
8
9
10
11
12
15
And this is the procedure:
CREATE PROCEDURE `ResumenVentasGeneralSucursal`(fecha_inicio DATE, fecha_fin DATE)
BEGIN
DECLARE fecha_inicio DATE DEFAULT fecha_inicio;
DECLARE fecha_fin DATE DEFAULT fecha_fin;
DECLARE total_bol INT default 0;
DECLARE total_fact INT default 0;
DECLARE total_nota_credito INT default 0;
DECLARE total INT DEFAULT 0;
DECLARE prom DOUBLE DEFAULT 0;
DECLARE suc_fetch INT;
DECLARE done INT DEFAULT FALSE;
DECLARE cursor_1 CURSOR FOR
SELECT DISTINCT(num_suc_bsale)
FROM documentos_historico
WHERE num_suc_bsale IS NOT NULL
ORDER BY num_suc_bsale DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
DROP TABLE IF EXISTS resumen_ventas_gen;
CREATE TEMPORARY TABLE resumen_ventas_gen(id int not null auto_increment primary key,total_venta INT, total_boleta INT, total_factura INT, total_nc INT, promedio DOUBLE, mes DATE, sucursal INT);
OPEN cursor_1;
suc_loop: LOOP
FETCH cursor_1 INTO suc_fetch;
IF done THEN
LEAVE suc_loop;
END IF;
WHILE fecha_inicio <= fecha_fin DO
SET total_bol = (SELECT SUM(CASE WHEN tipo_documento = 22 THEN total_venta ELSE 0 END) as total_boleta FROM documentos_historico WHERE num_suc_bsale = suc_fetch AND DATE_FORMAT(fecha_generacion_bsale, '%Y-%m') = DATE_FORMAT(fecha_inicio, '%Y-%m'));
SET total_fact = (SELECT SUM(CASE WHEN tipo_documento = 5 THEN total_venta ELSE 0 END) as total_factura FROM documentos_historico WHERE num_suc_bsale = suc_fetch AND DATE_FORMAT(fecha_generacion_bsale, '%Y-%m') = DATE_FORMAT(fecha_inicio, '%Y-%m'));
SET total_nota_credito = (SELECT SUM(CASE WHEN tipo_documento = 2 THEN total_venta ELSE 0 END) as total_credito FROM documentos_historico WHERE num_suc_bsale = suc_fetch AND DATE_FORMAT(fecha_generacion_bsale, '%Y-%m') = DATE_FORMAT(fecha_inicio, '%Y-%m'));
SET total = (SELECT SUM(total_venta) as total_venta FROM documentos_historico WHERE num_suc_bsale = suc_fetch AND DATE_FORMAT(fecha_generacion_bsale, '%Y-%m') = DATE_FORMAT(fecha_inicio, '%Y-%m'));
SET prom = (SELECT AVG(total_venta) as promedio FROM documentos_historico WHERE num_suc_bsale = suc_fetch AND DATE_FORMAT(fecha_generacion_bsale, '%Y-%m') = DATE_FORMAT(fecha_inicio, '%Y-%m'));
INSERT INTO resumen_ventas_gen(total_venta, total_boleta, total_factura, total_nc, promedio, mes, sucursal) VALUES(total, total_bol, total_fact, total_nota_credito, prom, fecha_inicio, suc_fetch);
SET fecha_inicio = fecha_inicio + INTERVAL 1 MONTH;
END WHILE;
END LOOP suc_loop;
CLOSE cursor_1;
SELECT
*
FROM
resumen_ventas_gen;
END
I don't know if I miss something in the cursor or something like that.
Any help would be appriciated.

How to two used while Syntax in Mysql Procecure

I would like to write two While Syntax.
The results I expect are as follows.
when 'H'
tagName1, tagName2, tagname3
when 'D'
tagName1, tagName2, tagname3
when 'M'
tagName1, tagName2, tagname3
when 'Y'
tagName1, tagName2, tagname3
But it didn't worked....
Below is the code that I wrote, while I play it only once.
Any advice, please..
DECLARE tagList varchar(255) DEFAULT 'tagName1,tagName2,tagName3';
DECLARE tagTypeList varchar(150) DEFAULT 'H,D,M,Y';
WHILE tagTypeList != '' DO
WHILE tagList != '' DO
SET tagNameArray = SUBSTRING_INDEX(tagList, ',', 1);
SET tagTypeArray = SUBSTRING_INDEX(tagTypeList, ',', 1);
IF(tagTypeArray = 'H') THEN
SET aDate = (SELECT (DATE_ADD(nDateTime, INTERVAL -1 HOUR)));
SET ago_Y = (SELECT DATE_FORMAT(aDate,'%Y'));
SET ago_M = (SELECT DATE_FORMAT(aDate,'%m'));
SET ago_D = (SELECT DATE_FORMAT(aDate,'%d'));
SET ago_H = (SELECT DATE_FORMAT(aDate,'%H'));
SET ago_W = (SELECT DATE_FORMAT(aDate,'%w'));
ELSEIF(tagTypeArray = 'D') THEN
SET aDate = (SELECT (DATE_ADD(nDateTime, INTERVAL -1 DAY)));
SET ago_Y = (SELECT DATE_FORMAT(aDate,'%Y'));
SET ago_M = (SELECT DATE_FORMAT(aDate,'%m'));
SET ago_D = (SELECT DATE_FORMAT(aDate,'%d'));
SET ago_H = 0;
SET ago_W = 0;
ELSEIF(tagTypeArray = 'M') THEN
SET aDate = (SELECT (DATE_ADD(nDateTime, INTERVAL -1 MONTH)));
SET ago_Y = (SELECT DATE_FORMAT(aDate,'%Y'));
SET ago_M = (SELECT DATE_FORMAT(aDate,'%m'));
SET ago_D = 0;
SET ago_H = 0;
SET ago_W = 0;
ELSEIF(tagTypeArray = 'Y') THEN
SET aDate = (SELECT (DATE_ADD(nDateTime, INTERVAL -1 YEAR)));
SET ago_Y = (SELECT DATE_FORMAT(aDate,'%Y'));
SET ago_M = 0;
SET ago_D = 0;
SET ago_H = 0;
SET ago_W = 0;
END IF;
SET selectValue = (SELECT tagvalue FROM datasource WHERE tagname = tagNameArray and tagtype = tagTypeArray and y=ago_Y and m=ago_M and d=ago_D and h=ago_H);
IF(selectValue IS NULL OR selectValue = '')
THEN
SET old_Value_3M = (Select LastValue from BwAnalogTable where TagName = tagNameArray and LogDate >= ago_3M order by LogDate desc, LogTime desc limit 1);
# Here Insert Querty
END IF;
IF LOCATE(',', tagList) > 0 THEN
SET tagList = SUBSTRING(tagList, LOCATE(',', tagList) + 1);
ELSE
SET tagList = '';
END IF;
END WHILE;
IF LOCATE(',', tagTypeList) > 0 THEN
SET tagTypeList = SUBSTRING(tagTypeList, LOCATE(',', tagTypeList) + 1);
ELSE
SET tagTypeList = '';
END IF;
END WHILE;
I have modified the code as shown below.
DECLARE done INT DEFAULT FALSE;
DECLARE tagType2 VARCHAR(255) DEFAULT '';
DECLARE tagName2 VARCHAR(255) DEFAULT '';
DECLARE tagType_Cur CURSOR for select tagType from tbtagtype;
DECLARE tagName_Cur CURSOR for select tagName from tbtaglist;
OPEN tagType_Cur;
LOOP1: LOOP
FETCH tagType_Cur INTO tagType2;
IF done THEN
CLOSE tagType_Cur;
LEAVE LOOP1;
END IF;
########## here insert your core query ###############
OPEN tagName_Cur;
LOOP2: LOOP
FETCH tagName_Cur INTO tagName2;
IF done THEN
CLOSE tagName_Cur;
SET done = FALSE;
LEAVE LOOP2;
END IF;
########## here insert your core query ###############
END LOOP LOOP2;
END LOOP LOOP1;

Date is not getting set

I have a procedure that should always set a date, but it does not:
CREATE PROCEDURE 'player_extend_membership` (pid INTEGER, daysToAdd INTEGER, OUT result INTEGER)
BEGIN
SELECT PlayerMembershipEndDate INTO #memDate FROM players WHERE players.PlayerID = pid LIMIT 1;
SELECT ROW_COUNT() INTO #num;
IF #num = 0 THEN
SET result = -1;
ELSE
IF #memDate = NULL OR DATE(#memDate) < DATE(NOW()) THEN
SET #finalDate = DATE_ADD(DATE(NOW()), INTERVAL daysToAdd DAY);
ELSE
SET #finalDate = DATE_ADD(DATE(#memDate), INTERVAL daysToAdd DAY);
END IF;
SELECT #finalDate, #memDate;
UPDATE players SET PlayerMembershipEndDate = #finalDate
WHERE players.PlayerID = pid;
SET result = 1;
END IF;
END
When I check the return value, it is 1, therefore the account does exist. It tells me the result of the select query is always that #finalDate is NULL.
However, if ake it out of the IF and just do:
SET #finalDate = DATE_ADD(DATE(NOW()), INTERVAL daysToAdd DAY);
The date is set correctly.
I'm not sire what I am doing wrong.
Thanks
Your procedure seems way too complicated. Perhaps this does what you want:
set #result = -1;
UPDATE players
SET PlayerMembershipEndDate = (case when (#result := 1) is null then NULL
when #memDate IS NULL OR DATE(#memDate) < DATE(NOW())
then DATE_ADD(DATE(NOW()), INTERVAL daysToAdd DAY)
else DATE_ADD(DATE(#memDate), INTERVAL daysToAdd DAY)
end)
WHERE players.PlayerID = pid;
The first condition in the case just sets #result if a row is found. I've left your formulation of DATE(NOW()) even though CURDATE() is more succinct.
I suspect the actual problem with your logic was the = NULL. This always returns "UNKNOWN", which is treated as false. The correct expression is is NULL.

Creating function error sql server 2008

I want to create a fucntion, but getting error.
below is query:
CREATE FUNCTION WFSlaTimer
(
#OBJECT_PK_ID INT = 110
)
RETURNS TABLE
AS BEGIN
DECLARE
#TIMER_START_ACTIVITY_ID INT,
#TIMER_START_ACTIVITY_COMPLETED_ON DATETIME,
#TIMER_END_ACTIVITY_ID INT,
#TIMER_END_ACTIVITY_COMPLETED_ON DATETIME,
#SLA_TIME_SCHEDULE_IN_DAYS INT,
#SLA_DISPLAY VARCHAR(20),
#START_DATE DATETIME,
#END_DATE DATETIME,
#BUSINESS_START_TIME VARCHAR(10),
#BUSINESS_END_TIME VARCHAR(10),
#BUSINESS_HOURS INT,
#SLA_CUT_OFF_TIME VARCHAR(10),
#IS_OBJECT_STATUS_IS_TERMINAL INT,
#COMPLETED_ACTION_ID INT,
#UNCHECKED_ACTION_ID INT,
#DAY_ADDED INT
SELECT #IS_OBJECT_STATUS_IS_TERMINAL = CASE when wos.FLG_STATUS_TYPE = 'W' THEN 0 ELSE 1 END
FROM WF.WF_OBJECT_INSTANCE woi
INNER JOIN WF.WF_OBJECT_STATUS wos ON wos.OBJECT_STATUS_ID = woi.OBJECT_STATUS_ID
WHERE woi.LINK_PK_ID = #OBJECT_PK_ID
SET #SLA_TIME_SCHEDULE_IN_DAYS = (SELECT CASE WHEN s.SLA_SCHEDULE_ID = 1 THEN lr.RUSH_NO_OF_DAYS ELSE s.NUM_OF_DAYS END --1= [RUSH]
FROM loan.LOAN_REQUEST lr
INNER JOIN WF.WF_SLA_SCHEDULE s
ON s.SLA_SCHEDULE_ID = ISNULL(lr.SLA_SCHEDULE_ID, 2) --{2= SLA-Schedule 5 Days}
WHERE lr.LOAN_REQUEST_ID = #OBJECT_PK_ID)
SET #SLA_DISPLAY = (SELECT
CASE WHEN s.SLA_SCHEDULE_ID = 1 THEN s.DISPLAY_NAME + ' (' + CAST(lr.RUSH_NO_OF_DAYS AS VARCHAR) + ')' ELSE s.DISPLAY_NAME END --1= [RUSH]
FROM loan.LOAN_REQUEST lr
INNER JOIN WF.WF_SLA_SCHEDULE s
ON s.SLA_SCHEDULE_ID = ISNULL(lr.SLA_SCHEDULE_ID, 2) --{2= SLA-Schedule 5 Days}
WHERE lr.LOAN_REQUEST_ID = #OBJECT_PK_ID)
SET #BUSINESS_START_TIME = (SELECT s.CONFIG_VALUE FROM SYS_CONFIG_ENTRY s WHERE s.NAME = 'BUSINESS_START_TIME')
SET #BUSINESS_END_TIME = (SELECT s.CONFIG_VALUE FROM SYS_CONFIG_ENTRY s WHERE s.NAME = 'BUSINESS_END_TIME')
SET #BUSINESS_HOURS = (SELECT CAST(DATEDIFF(hour, CAST(#BUSINESS_START_TIME AS DATETIME), CAST(#BUSINESS_END_TIME AS DATETIME)) AS INT))
SET #SLA_CUT_OFF_TIME = (SELECT DATEPART(hour, CAST(s.CONFIG_VALUE AS TIME)) FROM SYS_CONFIG_ENTRY s WHERE s.NAME = 'SLA_CUT_OFF_TIME')
SET #COMPLETED_ACTION_ID = (SELECT ACTION_TYPE_ID FROM WF.WF_ACTION_TYPE WHERE NAME = 'ACTIVITY_COMPLETED')
SET #UNCHECKED_ACTION_ID = (SELECT ACTION_TYPE_ID FROM WF.WF_ACTION_TYPE WHERE NAME = 'ACTIVITY_UNCHECKED')
--GET SLA TIMER ACTIVITY IDs
SELECT #TIMER_START_ACTIVITY_ID = t.START_ACTIVITY_ID,
#TIMER_END_ACTIVITY_ID = t.END_ACTIVITY_ID
FROM [WF].WF_TIMER t
WHERE t.NAME = 'SLA_TIMER'
--Get START ACTIVITY ON
SELECT #TIMER_START_ACTIVITY_COMPLETED_ON = ACTION_ON
FROM [WF].WF_OBJECT_ACTIVITY_HISTORY woah
WHERE LINK_PK_ID = #OBJECT_PK_ID
AND woah.ACTIVITY_ID = #TIMER_START_ACTIVITY_ID
AND ACTION_ID = #COMPLETED_ACTION_ID
AND
--{
woah.APPLICATION_HISTORY_ID > ISNULL((SELECT TOP 1 ISNULL(APPLICATION_HISTORY_ID, 0)
FROM WF.WF_OBJECT_ACTIVITY_HISTORY
WHERE LINK_PK_ID = #OBJECT_PK_ID
AND ACTIVITY_ID = #TIMER_START_ACTIVITY_ID
AND ACTION_ID = #UNCHECKED_ACTION_ID
ORDER BY ACTION_ON DESC
), 0)
--}
--AND
----{
--0 = ISNULL((SELECT TOP 1 ISNULL(APPLICATION_HISTORY_ID, 0)
-- FROM WF.WF_OBJECT_ACTIVITY_HISTORY
-- WHERE LINK_PK_ID = #OBJECT_PK_ID
-- AND ACTIVITY_ID = #TIMER_END_ACTIVITY_ID
-- AND ACTION_ID = #COMPLETED_ACTION_ID
-- ORDER BY ACTION_ON DESC), 0)
----}
ORDER BY ACTION_ON DESC
--Get END ACTIVITY ON
SELECT #TIMER_END_ACTIVITY_COMPLETED_ON = ACTION_ON
FROM [WF].WF_OBJECT_ACTIVITY_HISTORY woah
WHERE LINK_PK_ID = #OBJECT_PK_ID
AND woah.ACTIVITY_ID = #TIMER_END_ACTIVITY_ID
AND ACTION_ID = #COMPLETED_ACTION_ID
AND
--{
woah.APPLICATION_HISTORY_ID > ISNULL((SELECT TOP 1 ISNULL(APPLICATION_HISTORY_ID, 0)
FROM WF.WF_OBJECT_ACTIVITY_HISTORY
WHERE LINK_PK_ID = #OBJECT_PK_ID
AND ACTIVITY_ID = #TIMER_END_ACTIVITY_ID
AND ACTION_ID = #UNCHECKED_ACTION_ID
ORDER BY ACTION_ON DESC
), 0)
--}
ORDER BY ACTION_ON DESC
--TO DO
--SET #TIMER_START_ACTIVITY_COMPLETED_ON = '2014-05-15 02:40:21.100'
--SET #TIMER_END_ACTIVITY_COMPLETED_ON = '2014-05-14 12:40:21.100'
SET #START_DATE = #TIMER_START_ACTIVITY_COMPLETED_ON
SET #DAY_ADDED = #SLA_TIME_SCHEDULE_IN_DAYS -- SLA Schedule Days
+ CASE WHEN DATEPART(hour, #TIMER_START_ACTIVITY_COMPLETED_ON) >= #SLA_CUT_OFF_TIME THEN 0 ELSE -1 END -- SLA Cut Off Time
SET #END_DATE = #START_DATE + #DAY_ADDED
--Exclud Holidays
--{
DECLARE #START_ON_DATE DATETIME = CAST(#START_DATE AS DATE)
WHILE #DAY_ADDED > 0
BEGIN
SELECT #END_DATE = #START_ON_DATE + #DAY_ADDED
--COUNT NO OF HOLIDAYS IF FALLING WITHIN START-DATE AND END-DATE
SELECT #DAY_ADDED = COUNT(*) FROM [WF].WF_CALENDAR WC --HOLIDAY LIST
WHERE WC.DATE BETWEEN #START_ON_DATE+1 AND #END_DATE AND (WC.IS_WEEKEND = 1 OR WC.IS_HOLIDAY = 1)
SET #START_ON_DATE = #END_DATE
END
--}
SET #END_DATE = (CAST(CAST(CAST(#END_DATE AS DATE) AS DATETIME) + CAST(#BUSINESS_END_TIME AS TIME) AS DATETIME))
;WITH TIMER_CTE AS (
SELECT #START_DATE AS OBJECT_CREATED_ON,
#END_DATE AS OBJECT_END_ON,
DIFFERENCE_IN_DAYS = DATEDIFF(dd, GETDATE(), #END_DATE),
TODAY_REMAINING_MINUTES =
CASE WHEN CONVERT(VARCHAR(10), #END_DATE, 112) >= CONVERT(VARCHAR(10), GETDATE(), 112)
THEN DATEDIFF(minute, GETDATE(), (CAST(CAST(CAST(GETDATE() AS DATE) AS DATETIME) + CAST(#BUSINESS_END_TIME AS TIME) AS DATETIME)))
ELSE 0 END,
TODAY_REMAINING_HOURS =
CASE WHEN CONVERT(VARCHAR(10), #END_DATE, 112) >= CONVERT(VARCHAR(10), GETDATE(), 112)
THEN (DATEDIFF(minute, GETDATE(), (CAST(CAST(CAST(GETDATE() AS DATE) AS DATETIME) + CAST(#BUSINESS_END_TIME AS TIME) AS DATETIME)))/60)
ELSE 0 END
)
RETURN (
SELECT
IS_SHOW_SLA = CASE WHEN #TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
--OR #IS_OBJECT_STATUS_IS_TERMINAL = 1
--OR #TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
THEN 0
ELSE 1 END,
#START_DATE AS [START_DATE], #END_DATE AS [END_DATE],
SLA_TYPE = #SLA_DISPLAY,
SLA_DUE = CONVERT(VARCHAR(10), CONVERT(DATETIME, tc.OBJECT_END_ON, 1), 101),
#BUSINESS_END_TIME AS BUSINESS_END_TIME,
SLA_START_ACTIVITY_CHECKED_ON = tc.OBJECT_CREATED_ON,
SLA_END_ACTIVITY_CHECKED_ON = #TIMER_END_ACTIVITY_COMPLETED_ON,
SLA_MISSED = CASE WHEN
--TODAY_REMAINING_MINUTES <= 0
--AND CONVERT(VARCHAR(10), #END_DATE, 112) = CONVERT(VARCHAR(10), GETDATE(), 112)
--OR
( GETDATE()> #END_DATE)
OR #TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
THEN 'Missed' ELSE NULL END,
tc.TODAY_REMAINING_HOURS,
tc.TODAY_REMAINING_MINUTES,
LAST_DAY_TIME_REMAINING =
CASE
WHEN #TIMER_END_ACTIVITY_COMPLETED_ON <= #END_DATE THEN 'Successful Completed'
WHEN CONVERT(VARCHAR(10), #END_DATE, 112) = CONVERT(VARCHAR(10), GETDATE(), 112)
THEN
CASE WHEN
tc.TODAY_REMAINING_HOURS <=0 AND tc.TODAY_REMAINING_MINUTES > 0 THEN
CASE WHEN tc.TODAY_REMAINING_MINUTES = 1 THEN CAST(tc.TODAY_REMAINING_MINUTES AS VARCHAR) + ' min remaining'
ELSE CAST(tc.TODAY_REMAINING_MINUTES AS VARCHAR) + ' mins remaining' END
WHEN tc.TODAY_REMAINING_HOURS =1 THEN CAST(tc.TODAY_REMAINING_HOURS AS VARCHAR) + ' hour remaining'
WHEN tc.TODAY_REMAINING_HOURS >1 THEN CAST(tc.TODAY_REMAINING_HOURS AS VARCHAR) + ' hours remaining'
ELSE NULL
END
ELSE NULL
END,
REMAINING_DAYS = CASE WHEN tc.DIFFERENCE_IN_DAYS <=0 THEN '0 day'
WHEN tc.DIFFERENCE_IN_DAYS > 1 THEN CAST(tc.DIFFERENCE_IN_DAYS AS VARCHAR) + ' days '
ELSE CAST(tc.DIFFERENCE_IN_DAYS AS VARCHAR) + ' day ' END
FROM TIMER_CTE tc
)
END;
GO
I am getting this error:
Msg 156, Level 15, State 1, Procedure WFSlaTimer, Line 144
Incorrect syntax near the keyword 'RETURN'.
Msg 178, Level 15, State 1, Procedure WFSlaTimer, Line 144
A RETURN statement with a return value cannot be used in this context.
Msg 102, Level 15, State 31, Procedure WFSlaTimer, Line 189
Incorrect syntax near 'BEGIN'.
Any help please
There are two kind of function that return table. the inline function and multi-statement function. Yours is multi-statement. Here is the syntax for this:
--Transact-SQL Multistatement Table-valued Function Syntax
CREATE FUNCTION [ schema_name. ] function_name
( [ { #parameter_name [ AS ] [ type_schema_name. ] parameter_data_type
[ = default ] [READONLY] }
[ ,...n ]
]
)
RETURNS #return_variable TABLE <table_type_definition>
[ WITH <function_option> [ ,...n ] ]
[ AS ]
BEGIN
function_body
RETURN
END
[ ; ]
For more information refer to CREATE FUNCTION (Transact-SQL) BOL documentation.
You have to define the returned table's structure (fields and data types)
1) Add a variable name to the function definition (#tableVariable in the above example).
2) Fill the table definition (columns and datatypes)
3) Modify your function to insert the result into the defined table variable, then use an empty RETURN statement when the function should return.
1st step
CREATE FUNCTION WFSlaTimer
(
#OBJECT_PK_ID INT = 110
)
RETURNS #tableVariable TABLE (
IS_SHOW_SLA INT,
StartDate DATETIME2,
EndDate DATETIME2
/** List all of your returned columns like when you creating a table **/
)
AS
BEGIN
/** Do your stuff **/
INSERT INTO #tableVariable ( /* field list */) VALUES (/* value list */)
-- OR --
INSERT INTO #tableVariable ( /* field list */)
SELECT /* FieldList */ FROM myCTE
RETURN
END
2nd step
Modify your RETURN () statement like this:
INSERT INTO #tableVanriable (IS_SHOW_SLA , StartDate , EndDate)
SELECT
IS_SHOW_SLA = CASE WHEN #TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
--OR #IS_OBJECT_STATUS_IS_TERMINAL = 1
--OR #TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
THEN 0
ELSE 1 END,
#START_DATE AS [START_DATE], #END_DATE AS [END_DATE],
SLA_TYPE = #SLA_DISPLAY
/** .... **/
FROM TIMER_CTE tc
/** 3rd step **/
RETURN

get startdate and enddate from specified week of the month

I need to find start date and end date from specified (1/2/3/4/5) week of month. So that I can get the records where Date_Created comes in specified (1/2/3/4/5) Week.
For example if
I choose 1st week of febuary 2013 then
I want startdate = 2/1/2013 and enddate = 2/2/2013
I choose 2nd week of febuary 2013 then
I want startdate = 2/3/2013 and enddate = 2/9/2013
and similary for rest weeks.
I have SQL Server 2008 at Database Side. If anyone have Idea then Please Share.
Here is a query to get all weeks start and end dates for given month. So you can select from this query week you need:
SQLFiddle example
with C(i) as
( select CAST('2013-02-01' as datetime) i
UNION ALL
select DATEADD (day,1,i) i from C
where DATEADD (day,1,i)
<DATEADD(month,1,'2013-02-01')
), C1 as
(
select DATEPART(WEEK,i)-DATEPART(WEEK,'2013-02-01')+1 WeekOfMonth,i from C
)
select WeekOfMonth,min(i) StartDate, max(i) EndDate from C1 group by WeekOfMonth
I wrote a procedure to solve my problem which will take week no(1/2/3/4/5) as input and will return startdate and enddate
ALTER PROCEDURE dbo.SPGetStartAndEndDateofSpcifiedWeek
#Week int
AS
SET NOCOUNT ON
DECLARE #date DateTime
DECLARE #currdate DateTime
DECLARE #startdate DateTime
DECLARE #enddate DateTime
DECLARE #CurrWeek int
/*SET #date = CONVERT(date,GETDATE())*/
SET #currdate = CONVERT(date,GETDATE())
SET #CurrWeek = datediff(week, dateadd(week, datediff(week, 0, dateadd(month, datediff(month, 0, GETDATE()), 0)), 0), GETDATE() - 1) + 1
IF (#Week = 1)
BEGIN
IF (#CurrWeek = 1)
BEGIN SET #date = #currdate END
IF (#CurrWeek = 2)
BEGIN SET #date = #currdate - 7 END
IF (#CurrWeek = 3)
BEGIN SET #date = #currdate - 14 END
IF (#CurrWeek = 4)
BEGIN SET #date = #currdate - 21 END
IF (#CurrWeek = 5)
BEGIN SET #date = #currdate - 28 END
END
IF (#Week = 2)
BEGIN
IF (#CurrWeek = 1)
BEGIN SET #date = #currdate + 7 END
IF (#CurrWeek = 2)
BEGIN SET #date = #currdate END
IF (#CurrWeek = 3)
BEGIN SET #date = #currdate - 7 END
IF (#CurrWeek = 4)
BEGIN SET #date = #currdate - 14 END
IF (#CurrWeek = 5)
BEGIN SET #date = #currdate - 21 END
END
IF (#Week = 3)
BEGIN
IF (#CurrWeek = 1)
BEGIN SET #date = #currdate + 14 END
IF (#CurrWeek = 2)
BEGIN SET #date = #currdate + 7 END
IF (#CurrWeek = 3)
BEGIN SET #date = #currdate END
IF (#CurrWeek = 4)
BEGIN SET #date = #currdate - 7 END
IF (#CurrWeek = 5)
BEGIN SET #date = #currdate - 14 END
END
IF (#Week = 4)
BEGIN
IF (#CurrWeek = 1)
BEGIN SET #date = #currdate + 21 END
IF (#CurrWeek = 2)
BEGIN SET #date = #currdate + 14 END
IF (#CurrWeek = 3)
BEGIN SET #date = #currdate + 7 END
IF (#CurrWeek = 4)
BEGIN SET #date = #currdate END
IF (#CurrWeek = 5)
BEGIN SET #date = #currdate - 7 END
END
IF (#Week = 5)
BEGIN
IF (#CurrWeek = 1)
BEGIN SET #date = #currdate + 28 END
IF (#CurrWeek = 2)
BEGIN SET #date = #currdate + 21 END
IF (#CurrWeek = 3)
BEGIN SET #date = #currdate + 14 END
IF (#CurrWeek = 4)
BEGIN SET #date = #currdate + 7 END
IF (#CurrWeek = 5)
BEGIN SET #date = #currdate END
END
Select CONVERT(date, DATEADD(wk, DATEDIFF(wk, 0, #date), - 1)) as startdate,
CONVERT(date, DATEADD(wk, DATEDIFF(wk, 0, #date), 5)) as enddate
RETURN
I modified code given by Valex to get the exact output as I required.
CREATE PROCEDURE dbo.SPReturnStartEndDateOfSpecifiedWeek
#Week int,
#P_startdate DateTime OUTPUT,
#P_enddate DateTime OUTPUT
AS
/* SET NOCOUNT ON */
with C(i) as
(
select CAST((DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0)) as datetime) i
UNION ALL
select DATEADD (day,1,i) i from C
where DATEADD (day,1,i)<DATEADD(month,1,(DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0)))
),
C1 as
(
select DATEPART(WEEK,i)-DATEPART(WEEK,(DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0)))+1 WeekOfMonth,i from C
),
C2 as
(
select WeekOfMonth,min(i) StartDate, max(i) EndDate from C1 group by WeekOfMonth
)
Select #P_startdate = StartDate,
#P_enddate = EndDate
from C2
WHERE WeekOfMonth=#Week
RETURN
You can try this to get the start or end date for the week. Just provide a date for which you find the dates.
Logic is quite simple just get the start and end date of the week and then check if the start date is greater than the month date if so take the month date as the week start date else the start date of the week.
Fiddle a bit to get what you want
Here is the code:
DECLARE #date datetime
SET #date = '2013-01-30'
DECLARE #startdate datetime
DECLARE #enddate datetime
DECLARE #MonthStart datetime
Declare #MonthEnd datetime
SET #startdate = DATEADD(wk, DATEDIFF(wk, 6, #date), 6)
SET #enddate = DATEADD(dd,6, DATEADD(wk, DATEDIFF(wk, 6, #date), 6))
SET #monthStart = CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(#date)-1),#date),101)
SET #MonthEnd =CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(DATEADD(mm,1,#date))),DATEADD(mm,1,#date)),101)
--select #startdate wstart,#MonthStart monthstart,#enddate wend,#MonthEnd monthend
select
[date] = #date
,[week] = DATEPART(wk,#date)
,[WeekStartDate] = Case
WHEN #startdate <= #MonthStart then #MonthStart else #startdate
END
,[WeekEndDate] = Case
WHEN #enddate > #MonthEnd then #MonthEnd else #enddate
END
see here:
Fiddle