How to use IF condition in storedProcedure? - mysql

I am using a condition to lock the login account after a fixed number of attempts with the wrong password. The update portion is as follows :
loginAttempts (INT(1)) is read from login account first
DECLARE LoginAttempts INT(1);
UPDATE login SET
LOGIN_ACCOUNT_STATUS = (SELECT CASE (LoginAttempts > MaxLoginAttempts) WHEN 1 THEN 'LOCKED' ELSE 'ACTIVE' END),
LOGIN_LOGIN_ATTEMPTS = (SELECT CASE (#USER_FOUND AND #PASSWORD_CORRECT) WHEN 1 THEN 0 ELSE LOGIN_LOGIN_ATTEMPTS + 1 END),
LOGIN_LAST_LOGIN_DATE = (SELECT CASE (#USER_FOUND AND #PASSWORD_CORRECT) WHEN 1 THEN TransactionDateTime ELSE LOGIN_LAST_LOGIN_DATE END),
LOGIN_LAST_LOGIN_LOCATION = null
WHERE LOGIN_EMAIL = UserEmail;
When I set MaxLoginAttmpts at 5, the account gets locked at 11 (Greater than twice maxLoginAttempts).
If I set MaxLoginAttmpts at 2, the account gets locked at 5 (Greater than twice maxLoginAttempts).
Why is this ? Any help is appreciated.
Here I am adding the full stored procedure.
CREATE DEFINER=`pubuducg`#`%` PROCEDURE `CustomerAuthenticate`(IN UserEmail VARCHAR(100), IN PassWD VARCHAR(40), IN AccStatus VARCHAR(100),IN TransactionDateTime DATETIME, IN MaxLoginAttempts INT(1))
BEGIN
DECLARE LoginUserID INT(11);
DECLARE LoginEmail VARCHAR(50);
DECLARE LoginPassword TINYTEXT;
DECLARE LoginAttempts INT(1);
DECLARE AccountStatus VARCHAR(45);
DECLARE UserRoles VARCHAR(80);
SELECT
login.LOGIN_USER_ID,
login.LOGIN_EMAIL,
login.LOGIN_PASSWORD,
login.LOGIN_ACCOUNT_STATUS,
login.LOGIN_LOGIN_ATTEMPTS,
GROUP_CONCAT(user_role.USER_ROLE_ROLE SEPARATOR ',') AS ROLES
INTO
LoginUserID,
LoginEmail,
LoginPassword,
AccountStatus,
LoginAttempts,
UserRoles
FROM login
INNER JOIN user_role ON
user_role.USER_ROLE_USER_ID = login.LOGIN_USER_ID AND user_role.USER_ROLE_STATUS = AccStatus
WHERE login.LOGIN_EMAIL = UserEmail;
SET #USER_FOUND = found_rows();
SET #PASSWORD_CORRECT = IF((LoginPassword = PassWD AND AccountStatus = AccStatus), true, false);
UPDATE login SET
LOGIN_ACCOUNT_STATUS = (SELECT CASE (LoginAttempts > MaxLoginAttempts) WHEN 1 THEN 'LOCKED' ELSE 'ACTIVE' END),
LOGIN_LOGIN_ATTEMPTS = (SELECT CASE (#USER_FOUND AND #PASSWORD_CORRECT) WHEN 1 THEN 0 ELSE LOGIN_LOGIN_ATTEMPTS + 1 END),
LOGIN_LAST_LOGIN_DATE = (SELECT CASE (#USER_FOUND AND #PASSWORD_CORRECT) WHEN 1 THEN TransactionDateTime ELSE LOGIN_LAST_LOGIN_DATE END),
LOGIN_LAST_LOGIN_LOCATION = null
WHERE LOGIN_EMAIL = UserEmail;
SELECT
IF(#USER_FOUND AND #PASSWORD_CORRECT, LoginUserID,0) AS USER_ID,
#PASSWORD_CORRECT AS AUTHENTICATED,
#USER_FOUND AS USER_EXISTS,
AccountStatus AS ACCOUNT_STATUS,
IF(#USER_FOUND AND #PASSWORD_CORRECT, 0, LoginAttempts + 1) AS LOGIN_ATTEMPTS,
IF(#USER_FOUND AND #PASSWORD_CORRECT, UserRoles,null) AS USER_ROLES;
END

Related

MySql select statement with conditional where clause

I am trying to write a MySql statement with a conditional where clause.
something like this:
set #price = 5000 ;
set #city = 1324368075;
select count(*)
from property
where case when #price is not null then
price < #price
end
and (case when #city is not null then
CityId = #city
end)
the variable should be included in the query only if it is not null.
My attempts have failed so far. Any ideas?
Edited:
Sorry I spoke too soon ysth,
these two queries are supposed to yield the same count but they dont.
Edit #2: Execution plan & indexes
Here's the query:
set #CountryId = null ;
set #CityId = 1324368075 ;
set #StateProvince = null ;
set #CategoryId = null ;
set #TransactionTypeId = null;
set #Price = 5000;
SELECT
Count(*)
FROM
meerkat.property
WHERE
(CASE WHEN #CountryId IS NOT NULL THEN CountryId = #CountryId ELSE 1 END)
AND (CASE WHEN #CityId IS NOT NULL THEN CityId = #CityId ELSE 1 END)
AND (CASE WHEN #CategoryId IS NOT NULL THEN CategoryId = #CategoryId ELSE 1 END)
AND (CASE WHEN #StateProvince IS NOT NULL THEN StateProvince = #StateProvince ELSE 1 END)
AND (CASE WHEN #TransactionTypeId IS NOT NULL THEN TransactionTypeId = #TransactionTypeId ELSE 1 END)
AND (CASE WHEN #Price IS NOT NULL THEN Price <= #Price ELSE 1 END)
AND IsPublic = 1
AND IsBlocked = 0;
Thanks in advance
If no when conditions are met, case returns null. If you want each test to pass, you need to return a true value instead, so:
case when #price is not null then
price < #price
else 1 end
and ...

error code 1048 column 'value' cannot be null

i have SP for update the data into new data with this query, so basically every id have own value for own rule_id, and this SP is to update the data with the new one from the SP
CREATE DEFINER=`root`#`localhost` PROCEDURE `update_discount_campaign_advanced2`(IN DiscountCampaignId INT(10),
IN rule_percentage VARCHAR(255),
IN rule_quota_daily_max VARCHAR(255),
IN rule_discount_daily VARCHAR(255),
IN rule_discount_weekly VARCHAR (255),
IN rule_discount_monthly VARCHAR(255),
IN rule_spesific_payment_method VARCHAR(255),
IN rule_spesific_cc_operator VARCHAR(255),
IN allow_other_product VARCHAR(255)
)
proc:
BEGIN
DECLARE is_discount_campaign_id INT(10);
DECLARE is_rule_percentage VARCHAR(255);
DECLARE is_rule_quota_daily_max VARCHAR(255);
DECLARE is_rule_discount_daily VARCHAR(255);
DECLARE is_rule_discount_weekly VARCHAR(255);
DECLARE is_rule_discount_monthly VARCHAR(255);
DECLARE is_rule_spesific_payment_method VARCHAR(255);
DECLARE is_rule_spesific_cc_operator VARCHAR(255);
DECLARE is_allow_other_product VARCHAR(255);
DECLARE param_1_message TEXT;
SET #is_discount_campaign_id = DiscountCampaignId;
SET #is_rule_percentage = rule_percentage;
SET #is_rule_quota_daily_max = rule_quota_daily_max;
SET #is_rule_discount_daily = rule_discount_daily;
SET #is_rule_discount_weekly = rule_discount_weekly;
SET #is_rule_discount_monthly = rule_discount_monthly;
SET #is_rule_spesific_payment_method = rule_spesific_payment_method;
SET #is_rule_spesific_cc_operator = rule_spesific_cc_operator;
SET #is_allow_other_product = allow_other_product;
SELECT CONVERT( CONCAT('Maaf, ID discount_campaign tidak bisa \'0\'') USING UTF8) INTO param_1_message;
IF (DiscountCampaignId = 0) THEN
SELECT param_1_message AS message;
LEAVE proc;
END IF;
IF (DiscountCampaignId != 0) THEN
INSERT INTO discount_campaign_advanced (id,discount_campaign_id,
discount_advanced_rules_id, value, createdAt, status, updatedAt)
select *, CASE WHEN
unitData.id is NULL THEN NULL ELSE NOW() END as updatedAt from (SELECT dca.id , DiscountCampaignId, dar.id as dar_id1, CASE WHEN dar.id = 1
THEN #is_rule_percentage WHEN dar.id = 2 THEN #is_rule_quota_daily_max
WHEN dar.id = 3 THEN #is_rule_discount_daily WHEN dar.id = 4
THEN #is_rule_discount_weekly WHEN dar.id = 5 THEN #is_rule_discount_monthly
WHEN dar.id = 6 THEN #is_rule_spesific_payment_method WHEN dar.id = 7
THEN #is_rule_spesific_cc_operator END, coalesce(dca.createdAt, NOW()), CASE when (dar.id = 1
and #is_rule_percentage != '0') THEN 1 WHEN (dar.id = 2 and
#is_rule_quota_daily_max != '0') THEN 1 WHEN
(dar.id = 3 and #is_rule_discount_daily != '0') THEN 1 WHEN (dar.id = 4 and
#is_rule_discount_weekly != '0') THEN 1
WHEN (dar.id = 5 AND #is_rule_discount_monthly != '0') THEN 1 WHEN (dar.id = 6
AND #is_rule_spesific_payment_method != '0')
THEN 1 WHEN (dar.id = 7 AND #is_rule_spesific_cc_operator != '0') THEN 1 ELSE 0 END as bb
FROM
discount_advanced_rules dar
LEFT JOIN
discount_campaign_advanced dca ON dca.discount_advanced_rules_id = dar.id
and dca.discount_campaign_id = DiscountCampaignId) as unitData
WHERE unitData.bb = 1
UNION
SELECT dca.id, DiscountCampaignId, dca.discount_advanced_rules_id, CASE WHEN dca.discount_advanced_rules_id = 1
THEN #is_rule_percentage WHEN dca.discount_advanced_rules_id = 2 THEN #is_rule_quota_daily_max
WHEN dca.discount_advanced_rules_id = 3 THEN #is_rule_discount_daily WHEN dca.discount_advanced_rules_id = 4
THEN #is_rule_discount_weekly WHEN dca.discount_advanced_rules_id = 5 THEN #is_rule_discount_monthly
WHEN dca.discount_advanced_rules_id = 6 THEN #is_rule_spesific_payment_method WHEN dca.discount_advanced_rules_id = 7
THEN #is_rule_spesific_cc_operator END, coalesce(dca.createdAt, NOW()), CASE when (dca.discount_advanced_rules_id = 1
and #is_rule_percentage != '0') THEN 1 WHEN (dca.discount_advanced_rules_id = 2 and
#is_rule_quota_daily_max != '0') THEN 1 WHEN
(dca.discount_advanced_rules_id = 3 and #is_rule_discount_daily != '0')
THEN 1 WHEN (dca.discount_advanced_rules_id = 4 and
#is_rule_discount_weekly != '0') THEN 1
WHEN (dca.discount_advanced_rules_id = 5
AND #is_rule_discount_monthly != '0') THEN 1 WHEN (dca.discount_advanced_rules_id = 6
AND #is_rule_spesific_payment_method != '0')
THEN 1 WHEN (dca.discount_advanced_rules_id = 7 AND #is_rule_spesific_cc_operator != '0') THEN 1 ELSE 0 END as bb,
NOW()
FROM discount_campaign_advanced dca
WHERE dca.discount_campaign_id = DiscountCampaignId
on duplicate key update id = values(id), discount_campaign_id = values(discount_campaign_id),
discount_advanced_rules_id = values(discount_advanced_rules_id), value = values(value),
createdAt = values(createdAt), status = values(status), updatedAt = values(updatedAt);
END IF;
IF (allow_other_product != 0) THEN
INSERT INTO discount_campaign_advanced (id,discount_campaign_id,
discount_advanced_rules_id, value, createdAt, status, updatedAt)
select *, CASE WHEN
unitData.id is NULL THEN NULL ELSE NOW() END as updatedAt from (SELECT dca.id , DiscountCampaignId, dar.id as dar_id1, CASE WHEN dar.id = 8
THEN #is_allow_other_product END, coalesce(dca.createdAt, NOW()), CASE when (dar.id = 8
and #is_allow_other_product != '0') THEN 1 ELSE 0 END as bb
FROM
discount_advanced_rules dar
LEFT JOIN
discount_campaign_advanced dca ON dca.discount_advanced_rules_id = dar.id
and dca.discount_campaign_id = DiscountCampaignId) as unitData
WHERE unitData.bb = 1
UNION
SELECT dca.id, DiscountCampaignId, dca.discount_advanced_rules_id, CASE WHEN dca.discount_advanced_rules_id = 8 THEN #is_allow_other_product END, coalesce(dca.createdAt, NOW()), CASE when (dca.discount_advanced_rules_id = 8
and #is_allow_other_product != '0') THEN 1 ELSE 0 END as bb,
NOW()
FROM discount_campaign_advanced dca
WHERE dca.discount_campaign_id = DiscountCampaignId
on duplicate key update id = values(id), discount_campaign_id = values(discount_campaign_id),
discount_advanced_rules_id = values(discount_advanced_rules_id), value = values(value),
createdAt = values(createdAt), status = values(status), updatedAt = values(updatedAt);
END IF;
END
but idk why when i call this SP call brambang_uom.update_discount_campaign_advanced2(2757, '5', '5', '1', '1', '1', '1', '1', '9');
it returns Error Code: 1048. Column 'value' cannot be null`, where my wrong at?

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

MySQL - trigger on before insert + if data already exists + enum column

I am working on a trigger that I though is quite easy and should work but it is not working.
Here is the (abstract) table structure:
PK_id | FK1_id | FK2_id | status
1 | 12 | 15 | 'ok'
status column is defined as enum('ok', 'ok_2', 'not_ok') NUT NULL with no default value.
The trigger should verify that a combination of both FKx_id values already exists and if yes it should set the status to 'ok_2', otherwise to 'ok' and if the status is set in the INSERT INTO it is not touched.
The trigger I have right now (only body!):
BEGIN
DECLARE cnt INT;
SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id);
IF cnt > 0 AND NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok';
END IF;
END
Unfortunately this trigger sets the status always to 'ok' - please notice that the status is not part of the INSERT query (thus considered as NULL). I have previously tried this trigger body with the same result:
BEGIN
IF (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id) > 0 AND NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok';
END IF;
END
and also this (with the very same result):
BEGIN
IF EXISTS(SELECT * FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id LIMIT 1) AND NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok';
END IF;
END
Can anyone tell me why the first condition is never met even if I am inserting the same FKx_id combination that is already present in the table?
EDIT: I switched the condition and the result is also the same - no 'ok_2' status set:
BEGIN
DECLARE cnt INT;
SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id);
IF cnt = 0 AND NEW.status IS NULL THEN
SET NEW.status = 'ok';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
END IF;
END
Got it.
The problem was this declaration of the status column:
status enum('ok', 'ok_2', 'not_ok') NOT NULL
which leads into status being pre-filled with the first enum's value if the status is not set in the INSERT statement. So the solution is next trigger body:
BEGIN
DECLARE cnt INT;
SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id);
IF cnt = 0 THEN
SET NEW.status = 'ok';
ELSEIF NEW.status = 'ok' THEN
SET NEW.status = 'ok_2';
END IF;
END
Now if I do this insert for the first time
INSERT INTO table (FK_1, FK_2) VALUES (100, 150)
the status is 'ok', if I insert this for the second time
INSERT INTO table (FK_1, FK_2) VALUES (100, 150)
the status is 'ok_2' and if I set the status explicitly like this:
INSERT INTO table (FK_1, FK_2, status) VALUES (100, 150, 'not_ok')
the status is 'not_ok'.
so, when working with enums that have no default value while are set as NOT NULL - do not expect them to be NULL on insert when omitted. The will be pre-filled probably with the first enums's value.

SELECT statement from table inside cursor loop force cursor to EXIT

New to MySQL Stored Procedures.
If I uncomment any of the 4 SELECT lines (Below) then the routine EXITS out of the FETCH loop. Do not understand why
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `UpdateStatusAudit`()
BEGIN
-- Create loop for all $Service records
DECLARE svc_id INT;
DECLARE test INT;
DECLARE svc_name VARCHAR(100);
DECLARE no_more_rows BOOLEAN;
DECLARE up_duration DECIMAL(11,2);
DECLARE down_duration DECIMAL(11,2);
DECLARE maint_duration DECIMAL(11,2);
DECLARE degr_duration DECIMAL(11,2);
DECLARE services_cur CURSOR FOR SELECT service_id,service_name FROM services ORDER BY service_id;
-- Declare 'handlers' for exceptions
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET no_more_rows = TRUE;
OPEN services_cur;
the_loop: LOOP
FETCH services_cur INTO svc_id,svc_name;
IF no_more_rows THEN
CLOSE services_cur;
LEAVE the_loop;
END IF;
SET up_duration = 0;
SET down_duration = 0;
SET maint_duration = 0;
SET degr_duration = 0;
SELECT svc_id;
BEGIN
-- SELECT IFNULL(sum(duration),0) INTO up_duration FROM daily_audit_summary where service_id = svc_id AND status = 'UP' AND Date = current_date - 1 group by date,service_id,status;
-- SELECT IFNULL(sum(duration),0) INTO down_duration FROM daily_audit_summary where service_id = svc_id AND status = 'DOWN' AND Date = current_date - 1 group by date,service_id,status;
-- SELECT IFNULL(sum(duration),0) INTO maint_duration FROM daily_audit_summary where service_id = svc_id AND status = 'MAINT' AND Date = current_date - 1 group by date,service_id,status;
-- SELECT IFNULL(sum(duration),0) INTO degr_duration FROM daily_audit_summary where service_id = svc_id AND status = 'DEGR' AND Date = current_date - 1 group by date,service_id,status;
END;
-- insert into daily_status
INSERT INTO daily_status (date,service_id,time_up,time_down,time_maint,time_degraded) values (current_date-1,svc_id,up_duration,down_duration,maint_duration,degr_duration);
END LOOP the_loop;
END
Did you try assigning the variables like this:
SELECT
up_duration := IFNULL(SUM(duration), 0)
FROM daily_audit_summary
WHERE service_id = svc_id
AND status = 'UP'
AND Date = current_date - 1
GROUP BY
date,
service_id,
status;
?
You could also combine all the assignments into a single SELECT:
SELECT
up_duration := SUM(CASE status WHEN 'UP' THEN duration ELSE 0 END)
down_duration := SUM(CASE status WHEN 'DOWN' THEN duration ELSE 0 END)
maint_duration := SUM(CASE status WHEN 'MAINT' THEN duration ELSE 0 END)
degr_duration := SUM(CASE status WHEN 'DEGR' THEN duration ELSE 0 END)
FROM daily_audit_summary
WHERE service_id = svc_id
AND status = 'UP'
AND Date = current_date - 1
GROUP BY
date,
service_id,
status;
But maybe you could avoid the cursor (and thus the loop) by using a single statement to do all the job:
INSERT INTO daily_status (
date,
service_id,
time_up,
time_down,
time_maint,
time_degraded
)
SELECT
d.Date,
s.service_id,
SUM(CASE das.status WHEN 'UP' THEN das.duration ELSE 0 END),
SUM(CASE das.status WHEN 'DOWN' THEN das.duration ELSE 0 END),
SUM(CASE das.status WHEN 'MAINT' THEN das.duration ELSE 0 END),
SUM(CASE das.status WHEN 'DEGR' THEN das.duration ELSE 0 END)
FROM services s
CROSS JOIN (SELECT CURRENT_DATE - 1 AS Date) AS d
LEFT JOIN daily_audit_summary AS das
ON s.service_id = das.service_id
AND das.Date = d.Date;
I guess that I needed to give a better explanation...
The Code is a Work In Progress and due to requirements, I cannot get rid of the "Services_cur" Cursor.
What I am finding is that when the query for the "Services_Cur" returns say 10 records and within the "the Loop" If I use a SELECT INTO statement from a TABLE such as
"SELECT F1 INTO MyVar from Atable where Afld = somevalue" the LOOP exits as if the "Services Cur" cursor was out of data???
If I issue a "SELECT 1234 INTO MyVar" the Loop works and I get 10 results (As Expected).
I am new to Stored Procedures for MySql and could not find an example of someone doing a series of "SELECT value for table" while within a Loop of FETCHES.
I hope this helps explain the issue better
Thanks for any help.