Mysql Procedure IF,ELSEIF Statment error - mysql

I try to create a procedure in mysql, but i get an syntax error, i don`t know why i get it and where is ''
# 1064 - You have an error in the RSQL syntax next to '' on line 4
My Procedure:
CREATE PROCEDURE MUWAP_VipAdd(IN szCharName varchar(10),IN DayAdd int,IN VipType smallint,IN datenow_srv datetime)
BEGIN
IF NOT EXISTS (SELECT 1 FROM `T_VIPList` WHERE AccountID = szCharName) THEN
INSERT INTO `T_VIPList` (`AccountID`,`Date`,`Type`) VALUES (szCharName,DATE_ADD(datenow_srv, INTERVAL DayAdd DAY),VipType);
ELSE IF EXISTS (SELECT 1 FROM `T_VIPList` WHERE AccountID = szCharName AND Date > datenow_srv) THEN
UPDATE `T_VIPList` SET `Date` = DATE_ADD(`Date`,INTERVAL DayAdd DAY) WHERE `AccountID` = szCharName;
UPDATE `T_VIPList` SET `Type` = VipType WHERE `AccountID` = szCharName AND `Type` < VipType;
ELSE
UPDATE `T_VIPList` SET `Date` = DATE_ADD(`Date`,INTERVAL DayAdd DAY), `Type` = VipType WHERE `AccountID` = szCharName;
END IF
END
Thank you!

In order to have multiple statements in a THEN statement, you need to use BEGIN...END.
CREATE PROCEDURE MUWAP_VipAdd(IN szCharName varchar(10),IN DayAdd int,IN VipType smallint,IN datenow_srv datetime)
BEGIN
IF NOT EXISTS (SELECT 1 FROM `T_VIPList` WHERE AccountID = szCharName)
THEN INSERT INTO `T_VIPList` (`AccountID`,`Date`,`Type`) VALUES (szCharName,DATE_ADD(datenow_srv, INTERVAL DayAdd DAY),VipType);
ELSE IF EXISTS (SELECT 1 FROM `T_VIPList` WHERE AccountID = szCharName AND Date > datenow_srv)
THEN BEGIN
UPDATE `T_VIPList` SET `Date` = DATE_ADD(`Date`,INTERVAL DayAdd DAY) WHERE `AccountID` = szCharName;
UPDATE `T_VIPList` SET `Type` = VipType WHERE `AccountID` = szCharName AND `Type` < VipType;
END
ELSE UPDATE `T_VIPList` SET `Date` = DATE_ADD(`Date`,INTERVAL DayAdd DAY), `Type` = VipType WHERE `AccountID` = szCharName;
END IF
END
You could also combine the two UPDATE queries into a single query:
UPDATE T_VIPList
SET Date = DATE_ADD(Date, INTERVAL DayAdd DAY),
Type = GREATEST(VipType, Type)
WHERE AccountID = szCharName;
In fact, it seems like the whole thing could be done with a single INSERT ... ON DUPLICATE KEY UPDATE query:
INSERT INTO T_VIPList (AccountID, Date, Type)
VALUES (szCharName,DATE_ADD(datenow_srv, INTERVAL DayAdd DAY),VipType)
ON DUPLICATE KEY UPDATE
Date = IF(Date > datenow_srv, VALUES(Date), Date),
Type = GREATEST(Type, VALUES(Type));

Related

I want to throw an exception when my mysql stored procedure doesn't find any results

I'm having trouble finding a way to throw an exception from a stored procedure if no data is found.
I need a way to check the query results in the if statement.
If the count is 0 then throw exception. If there's data then return the data.
CREATE DEFINER=`adminHC`#`%` PROCEDURE `find_user_with_credentials`(
IN `usernameIN` VARCHAR(45)
, IN `encryptedpwIN` VARCHAR(45)
)
BEGIN
SELECT *
FROM (SELECT distinct
userid
,firstname
,lastname
,publicname
,email
,addressid
,create_date
,update_date
,active
FROM dev_users
WHERE (email = usernameIN OR (
publicname IS NOT null AND
publicname = usernameIN
))
AND encryptedpw = encryptedpwIN
AND active = 1) user;
IF count(user) > 0 THEN
SELECT user;
ELSE
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = "Invalid username or password",
MYSQL_ERRNO = 403;
END IF;
END
Start with a SELECT COUNT(*) query and check the result of that.
CREATE DEFINER=`adminHC`#`%` PROCEDURE `find_user_with_credentials`(
IN `usernameIN` VARCHAR(45)
, IN `encryptedpwIN` VARCHAR(45)
)
BEGIN
IF (SELECT COUNT(*)
FROM dev_users
WHERE (email = usernameIN OR (
publicname IS NOT null AND
publicname = usernameIN
))
AND encryptedpw = encryptedpwIN
AND active = 1) > 0
THEN SELECT
userid
,firstname
,lastname
,publicname
,email
,addressid
,create_date
,update_date
,active
FROM dev_users
WHERE (email = usernameIN OR (
publicname IS NOT null AND
publicname = usernameIN
))
AND encryptedpw = encryptedpwIN
AND active = 1;
ELSE
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = "Invalid username or password",
MYSQL_ERRNO = 403;
END IF;
END
There's also no need for the SELECT * wrapper. And I doubt you need SELECT DISTINCT, since I assume you can't have multiple rows with the same userid, and there's nothing in the query that will duplicate rows.
If the query were too expensive to do twice, you could do it once and save the results in a temporary table. Then you can use SELECT COUNT(*) FROM temp_table to check if there are any results, and finally SELECT * FROM temp_table to return the data.

error 1310 while creating mysql procedure

I'm newbie with mysql procedures and I need to create lip_StoreItem procedure on mysql, but i'm getting this error
"[Err] 1310 - End-label $$ without match"
What is wrong here? or where i can get more info about that? I've tried to look for a solution on google, but it's too big deal for me :)
DELIMITER $$
/* Save item */
DROP PROCEDURE IF EXISTS `lip_StoreItem` $$
CREATE PROCEDURE `lip_StoreItem` (IN iItemID INTEGER UNSIGNED,
IN iOwnerID INTEGER UNSIGNED,
IN iItemType MEDIUMINT UNSIGNED,
IN iAmount BIGINT,
IN iSlot INTEGER,
IN eLoc ENUM('VOID','INVENTORY','PAPERDOLL','WAREHOUSE','FREIGHT','CLANWH','MAIL','PET_INVENTORY','PET_PAPERDOLL'),
IN iEnchant SMALLINT UNSIGNED,
IN iDuration INTEGER,
IN iPeriod INTEGER,
IN iAttackType TINYINT,
IN iAttackVal SMALLINT,
IN iDefFire SMALLINT,
IN iDefWater SMALLINT,
IN iDefWind SMALLINT,
IN iDefEarth SMALLINT,
IN iDefHoly SMALLINT,
IN iDefUnholy SMALLINT,
IN iVariStat1 SMALLINT UNSIGNED,
IN iVariStat2 SMALLINT UNSIGNED,
IN iBlessed INTEGER,
IN iDamaged INTEGER,
IN iItemEnergy INTEGER,
IN iCustomFlags INTEGER UNSIGNED,
IN iItemVisType MEDIUMINT UNSIGNED)
NOT DETERMINISTIC
SQL SECURITY DEFINER
entry: BEGIN
DECLARE iRowCount INTEGER DEFAULT 0;
IF (iAmount <= 0) OR (iDuration = 0) OR (iPeriod = 0) OR (iOwnerID = 0) THEN -- OR (eLoc = 'VOID')
CALL `lip_DeleteItem`(iItemID);
LEAVE entry;
END IF;
INSERT LOW_PRIORITY INTO `items` (
`item_id`,
`owner_id`,
`item_type`,
`amount`,
`location`,
`slot`,
`enchant`
) VALUES (
iItemID,
iOwnerID,
iItemType,
iAmount,
eLoc,
iSlot,
iEnchant
) ON DUPLICATE KEY UPDATE
`owner_id` = iOwnerID,
`item_type` = iItemType,
`amount` = iAmount,
`location` = eLoc,
`slot` = iSlot,
`enchant` = iEnchant;
SET iRowCount = ROW_COUNT();
-- SELECT 'lip_StoreItem[303]', iRowCount;
-- TODO: ROW_COUNT() bug ???
CASE
WHEN iRowCount = 1 THEN -- insert new
BEGIN
IF iDuration > 0 THEN -- new item duration
INSERT LOW_PRIORITY INTO `items_duration` (
`item_id`,
`duration`
) VALUES (
iItemID,
iDuration
) ON DUPLICATE KEY UPDATE
`duration` = iDuration;
-- SELECT 'lip_StoreItem[316]', iItemID, iDuration, ROW_COUNT();
END IF;
IF iPeriod > 0 THEN -- new item period
INSERT LOW_PRIORITY INTO `items_period` (
`item_id`,
`period`
) VALUES (
iItemID,
iPeriod
) ON DUPLICATE KEY UPDATE
`period` = iPeriod;
-- SELECT 'lip_StoreItem[326]', iItemID, iPeriod, ROW_COUNT();
END IF;
IF ((iAttackType > -2) AND (iAttackVal > 0)) OR -- have attack or some defence in new item
(iDefFire > 0) OR (iDefWater > 0) OR
(iDefWind > 0) OR (iDefEarth > 0) OR
(iDefHoly > 0) OR (iDefUnholy > 0) THEN
INSERT LOW_PRIORITY INTO `items_attributes` (
`item_id`,
`attack_type`,
`attack_value`,
`defence_fire`,
`defence_water`,
`defence_wind`,
`defence_earth`,
`defence_holy`,
`defence_unholy`
) VALUES (
iItemID,
iAttackType,
iAttackVal,
iDefFire,
iDefWater,
iDefWind,
iDefEarth,
iDefHoly,
iDefUnholy
) ON DUPLICATE KEY UPDATE
`attack_type` = iAttackType,
`attack_value` = iAttackVal,
`defence_fire` = iDefFire,
`defence_water` = iDefWater,
`defence_wind` = iDefWind,
`defence_earth` = iDefEarth,
`defence_holy` = iDefHoly,
`defence_unholy` = iDefUnholy;
-- SELECT 'lip_StoreItem[353]', iItemID,iAttackType,iAttackVal,iDefFire,iDefWater,iDefWind,iDefEarth,iDefHoly,iDefUnholy,ROW_COUNT();
END IF;
IF (iVariStat1 > 0) OR (iVariStat2 > 0) THEN -- have some variation(augumentation) in new item
INSERT LOW_PRIORITY INTO `items_variation` (
`item_id`,
`stat1`,
`stat2`
) VALUES (
iItemID,
iVariStat1,
iVariStat2
) ON DUPLICATE KEY UPDATE
`stat1` = iVariStat1,
`stat2` = iVariStat2;
-- SELECT 'lip_StoreItem[365]', iItemID, iVariStat1, iVariStat2, ROW_COUNT();
END IF;
IF (iBlessed > 0) OR (iDamaged > 0) OR (iItemEnergy > 0) OR (iCustomFlags > 0) OR (iItemVisType > 0) THEN -- have some rare or custom flag in item
INSERT LOW_PRIORITY INTO `items_options` (
`item_id`,
`blessed`,
`damaged`,
`energy`,
`flags`,
`item_vis_type`
) VALUES (
iItemID,
iBlessed,
iDamaged,
iItemEnergy,
iCustomFlags,
iItemVisType
) ON DUPLICATE KEY UPDATE
`blessed` = iBlessed,
`damaged` = iDamaged,
`energy` = iItemEnergy,
`flags` = iCustomFlags,
`item_vis_type` = iItemVisType;
-- SELECT 'lip_StoreItem[381]', iItemID, iBlessed, iDamaged, iItemEnergy, iCustomFlags, ROW_COUNT();
END IF;
END;
WHEN (iRowCount = 0) OR (iRowCount = 2) OR (iRowCount = 3) THEN -- not changed or updated or Bug#46675(or toad for mysql future?)
BEGIN
IF iDuration > 0 THEN
UPDATE LOW_PRIORITY `items_duration` SET `duration` = iDuration WHERE `item_id` = iItemID LIMIT 1;
-- INSERT LOW_PRIORITY INTO `items_duration` (
-- `item_id`,
-- `duration`
-- ) VALUES (
-- iItemID,
-- iDuration
-- ) ON DUPLICATE KEY UPDATE
-- `duration` = iDuration;
-- SELECT 'lip_StoreItem[395]', iItemID, iDuration, ROW_COUNT();
END IF;
IF iPeriod > 0 THEN
UPDATE LOW_PRIORITY `items_period` SET `period` = iPeriod WHERE `item_id` = iItemID LIMIT 1;
-- INSERT LOW_PRIORITY INTO `items_period` (
-- `item_id`,
-- `period`
-- ) VALUES (
-- iItemID,
-- iPeriod
-- ) ON DUPLICATE KEY UPDATE
-- `period` = iPeriod;
-- SELECT 'lip_StoreItem[407]', iItemID, iDuration, ROW_COUNT();
END IF;
IF ((iAttackType > -2) AND (iAttackVal > 0)) OR -- have attack or some defence
(iDefFire > 0) OR (iDefWater > 0) OR
(iDefWind > 0) OR (iDefEarth > 0) OR
(iDefHoly > 0) OR (iDefUnholy > 0) THEN
INSERT LOW_PRIORITY INTO `items_attributes` ( -- add new or update old
`item_id`,
`attack_type`,
`attack_value`,
`defence_fire`,
`defence_water`,
`defence_wind`,
`defence_earth`,
`defence_holy`,
`defence_unholy`
) VALUES (
iItemID,
iAttackType,
iAttackVal,
iDefFire,
iDefWater,
iDefWind,
iDefEarth,
iDefHoly,
iDefUnholy
) ON DUPLICATE KEY UPDATE
`attack_type` = iAttackType,
`attack_value` = iAttackVal,
`defence_fire` = iDefFire,
`defence_water` = iDefWater,
`defence_wind` = iDefWind,
`defence_earth` = iDefEarth,
`defence_holy` = iDefHoly,
`defence_unholy` = iDefUnholy;
-- SELECT 'lip_StoreItem[443]', iItemID,iAttackType,iAttackVal,iDefFire,iDefWater,iDefWind,iDefEarth,iDefHoly,iDefUnholy,ROW_COUNT();
ELSE -- or delete (eg remove attribute)
DELETE LOW_PRIORITY FROM `items_attributes` WHERE `item_id` = iItemID LIMIT 1;
-- SELECT 'lip_StoreItem[447]', iItemID,iAttackType,iAttackVal,iDefFire,iDefWater,iDefWind,iDefEarth,iDefHoly,iDefUnholy,ROW_COUNT();
END IF;
IF (iVariStat1 > 0) OR (iVariStat2 > 0) THEN -- have some new variation(augumentation) in existing item
INSERT INTO `items_variation` (
`item_id`,
`stat1`,
`stat2`
) VALUES (
iItemID,
iVariStat1,
iVariStat2
) ON DUPLICATE KEY UPDATE
`stat1` = iVariStat1,
`stat2` = iVariStat2;
-- SELECT 'lip_StoreItem[462]', iVariStat1, iVariStat2, ROW_COUNT();
ELSE -- delete variation (variation was removed or newer exists)
DELETE LOW_PRIORITY FROM `items_variation` WHERE `item_id` = iItemID LIMIT 1;
-- SELECT 'lip_StoreItem[465]', iVariStat1, iVariStat2, ROW_COUNT();
END IF;
IF (iBlessed > 0) OR (iDamaged > 0) OR (iItemEnergy > 0) OR (iCustomFlags > 0) OR (iItemVisType > 0) THEN -- have some new rare or custom flag in item
INSERT LOW_PRIORITY INTO `items_options` (
`item_id`,
`blessed`,
`damaged`,
`energy`,
`flags`,
`item_vis_type`
) VALUES (
iItemID,
iBlessed,
iDamaged,
iItemEnergy,
iCustomFlags,
iItemVisType
) ON DUPLICATE KEY UPDATE
`blessed` = iBlessed,
`damaged` = iDamaged,
`energy` = iItemEnergy,
`flags` = iCustomFlags,
`item_vis_type` = iItemVisType;
-- SELECT 'lip_StoreItem[484]', iItemID, iBlessed, iDamaged, iItemEnergy, iCustomFlags, ROW_COUNT();
ELSE -- remove rare flags
DELETE LOW_PRIORITY FROM `items_options` WHERE `item_id` = iItemID LIMIT 1;
-- SELECT 'lip_StoreItem[487]', iItemID, iBlessed, iDamaged, iItemEnergy, iCustomFlags, ROW_COUNT();
END IF;
END;
ELSE
BEGIN
-- exception
-- SELECT 'lip_StoreItem[384] exception', iRowCount;
CALL `Unexpected ROW_COUNT() result in lip_StoreItem`;
END;
END CASE;
END $$
mysql answer what i get:
INSERT LOW_PRIORITY INTO `items_attributes` (
`item_id`,
`attack_type`,
`attack_value`,
`defence_fire`,
`defence_water`,
`defence_wind`,
`defence_earth`,
`defence_holy`,
`defence_unholy`
) VALUES (
iItemID,
iAttackType,
iAttackVal,
iDefFire,
iDefWater,
iDefWind,
iDefEarth,
iDefHoly,
iDefUnholy
) ON DUPLICATE KEY UPDATE
`attack_type` = iAttackType,
[Err] 1310 - End-label $$ without match

Struggling to get desired return

I'm relatively new to SQL, but am generally a quick learner and this particular query has stumped me for a few days. Any help would be beyond appreciated at this point.
When I run the below query, I only return rows where there exists a statusdatetime (the agent logged in that day). I need to return a row even when the agent didn't log in but was scheduled. How can I change this query to return a NULL for that. I thought the left join would work.
DECLARE #startDate datetime
DECLARE #endDate datetime
SET #startDate = GETDATE()
SET #endDate = GETDATE()
SET #startDate = CONVERT(DATETIME, CONVERT(varchar(11),#startDate, 111 ) + ' 00:00:00', 111)
SET #endDate = CONVERT(DATETIME, CONVERT(varchar(11),#endDate, 111 ) + ' 23:59:59', 111)
Begin
Create table #boris5table(
Firstname varchar(50),
lastname varchar (50),
username varchar (50),
starttime datetime,
loggedintime datetime,
variation int)
End
Insert into #boris5table (Firstname, lastname, username, starttime, loggedintime, variation)
Select firstname, lastname, userid,
(cast(DATEADD(MINUTE, (-300 +
(select min(startoffset) from [dbo].[IO_ScheduleInterval]
Where activitytypeid = '0000000000000000000004'
and PaidTime = '1'
and f1.agentid = f2.agentid
and ScheduleID = f1.scheduleid)), StartDateTimeUTC) as datetime)),
case when exists (select count(*), statusdatetime from [dbo].[AgentActivityLog] Where StatusDateTime between #startdate and #enddate Group by StatusDateTime) then min(statusdatetime)
Else NULL
End as LoggedInTime,
DATEDIFF(minute, (cast(DATEADD(MINUTE, (-300 +
(select min(startoffset) from [dbo].[IO_ScheduleInterval]
Where activitytypeid = '0000000000000000000004'
and PaidTime = '1'
and f1.agentid = f2.agentid
and ScheduleID = f1.scheduleid)), StartDateTimeUTC) as datetime)),
case when exists (select statusdatetime from [dbo].[AgentActivityLog] Where StatusDateTime between #startdate and #enddate and f3.UserId = f2.UserName) then min(statusdatetime)
Else 'NULL' END)
as 'Variation (minutes)'
From [I3_IC].[dbo].[IO_Schedule] as f1
left join [dbo].[IO_Agent] as f2 on f1.AgentID = f2.AgentID and (CAST(DATEADD(hour, - 5, f1.StartDateTimeUTC) as date)) between #startdate and #enddate
left join [dbo].[Individual] as f4 on f2.UserName = f4.WebLogin and LastName <> '-'
left join [dbo].[AgentActivityLog] as f3 on f2.UserName = f3.UserId and (CAST(DATEADD(hour, -1, f3.StatusDateTime) as date)) between #startdate and #enddate
Group by firstname, lastname, f2.UserName, ScheduleID, f1.AgentID, f2.AgentID, StartDateTimeUTC, f3.UserId
Select *
From #boris5table
drop table #boris5table

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