I have a stored procedure that for now is just suppose to validate your string input as a valid date. I've tried running this outside of a procedure and it works flawlessly, but as soon as I stick it in a procedure, the parameters get changed to zero.
My procedure is as follows:
CREATE PROCEDURE spDateRange
#DateMin varchar = NULL,
#DateMax varchar = NULL
AS
PRINT #DateMin;
PRINT #DateMax;
IF #DateMin IS NOT NULL AND #DateMax IS NOT NULL
BEGIN
PRINT #DateMin;
IF(ISDATE(#DateMin)=1 AND ISDATE(#DateMax)=1)
PRINT 'Valid Date';
ELSE
RAISERROR('Parameters not date format', 10, 1);
END
ELSE
RAISERROR ('Invalid parameters', 10, 1);
And my execute statement is:
EXECUTE spDateRange #DateMin='01/11/2011', #DateMax='01/12/2011';
And my output is:
0
0
0
Parameters not date format
You need to give an explicit length for the varchar parameters. It defaults to 1 character.
char(10) should be enough for valid dates in dd/mm/yyyy format but I guess you might want longer as this is validating potentially invalid dates!
CREATE PROCEDURE spDateRange
#DateMin varchar(30) = NULL,
#DateMax varchar(30) = NULL
AS
Related
So I have this stored function added in mysql workbench:
CREATE FUNCTION `getfullAdd` (id INT unsigned)
RETURNS VARCHAR(160)
CHARACTER SET utf8
COMMENT 'function that returns all addresses with character string when you enter customer number'
DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE addfound VARCHAR(160) CHARACTER SET utf8;
SELECT CONCAT_WS(', ', addr01, addr02) INTO addfound FROM dtb_customer WHERE customer_id=id;
RETURN addfound;
END
I'm bit new to this DETERMINISTIC keyword.
What does it do to the function above?
If set by this keyword, does function return the same value by the same parameter?
If customer's address is changed, does this function returns different result from the same parameter?
From the manual
"A routine is considered “deterministic” if it always produces the same result for the same input parameters, and “not deterministic” otherwise. "
https://dev.mysql.com/doc/refman/5.7/en/create-procedure.html
So your function is DETERMINISTIC as long as none of the customer id's change.
I have two function.
fn_validate_date
fn_validation
fn_validate_date code:
CREATE DEFINER=`root`#`localhost` FUNCTION `fn_validate_date`(
`dt_date` DATE
)
RETURNS date
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Returns the associated value of given attribute for given employee for a particular date.'
BEGIN
SET dt_date = IF(dt_date IS NULL OR dt_date ='', CURRENT_DATE, dt_date);
RETURN dt_date;
END
fn_validation code:
CREATE DEFINER=`root`#`localhost` FUNCTION `fn_validation`(
`dt_date` DATE
)
RETURNS date
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
RETURN fn_validate_date(dt_date);
END
Now when I am calling fn_validate_date as below
SELECT `fn_validate_date`(null);
It's working well but when I calling fn_validation it's giving me an error.
SELECT `fn_validation`(null);
My question is why I didn't get error while calling fn_validate_date?
In fn_validate_date, the dt_date-parameter is type of date and you are comparing it to a string datatype. No need for that. Date datatype cannot contain ''. It either is NULL or has a date value in it.
So instead of:
SET dt_date = IF(dt_date IS NULL OR dt_date ='', CURRENT_DATE, dt_date);
You can simply use:
return ifnull( dt_date, current_date() );
I disable strict mode and it's working well.
SET sql_mode =''
To disable strict mode in MySQL. I am not sure why MySql short-circuited IF condition as I am passing NULL in the input parameter of fn_validation.
I created a procedure on mysql.
Here's my sql.
drop procedure if exists proc_serial_no;
DELIMITER //
CREATE PROCEDURE `proc_serial_no`(IN comp_code varchar(20), IN meat_rule_one varchar(20),OUT serial_no int)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY INVOKER
COMMENT 'serial no generator for trace code'
begin
declare current_no int default 0;
select serial_no into current_no from t_serial_no where comp_code = comp_code and rule = meat_rule_one;
if current_no = 0
then insert into t_serial_no (id,no,comp_code,rule) values ( replace(uuid(),'-',''),1,comp_code,meat_rule_one);
else update t_serial_no set no = no + 1 where comp_code = comp_code and rule = meat_rule_one;
end if;
select serial_no = current_no + 1;
end
I'm expecting the out param [serial_no] to increase every time I call the procedure,but it's always zero.
When I change sql related to the out param to
select no into serial_no from t_serial_no where comp_code = comp_code and rule = meat_rule_one;
It worked!
I could't figure out why. Anyone can answer this would be in great help!
This may be right or wrong. But it may be due to ,
Everytime you call the procedure , the local variable current_no is by its default value it is 0.
When the scope moves out of the procedure and again when you call that procedure, it again starts with its default value 0 again and again.
And also,
May be everytime you pass the value 0 to serial_no param everytime you call that procedure and it again starts with 0 everytime when the scope moves out and comes in.
I have a stored procedure that returns a common query, I need to call it in several functions but some functions may call it through Period Id or others through Header Id, so far I would like to know how can I determine what param to use in order to retrive data properly, I have something like this implemented.
CREATE PROCEDURE dbo.GetTFDRecordInfo
#PeriodId int = null,
#HeaderId int = null
AS
BEGIN
SELECT
-- I have a lot more fields and joins here, that's why I need to get the statement in a single call through either period id or header id
*
From NT_CSRTNVPeriodInfo t
-- how can I make possible something like shown above, can I use a "Case When"?
Where (
/*
if #PeriodId is null
Where t.HeaderId = #HeaderId
if #HeaderId is null
Where t.PeriodId = #PeriodId
*/
)
END
GO
-- swtich between params
Exec NT_CSRTNVPeriodInfo null, 2654
Exec NT_CSRTNVPeriodInfo 196, null
This is the answer:
CREATE PROCEDURE dbo.GetTFDRecordInfo
#PeriodId int = null,
#HeaderId int = null
AS
BEGIN
SELECT
-- I have a lot more fields and joins here, that's why I need to get the statement in a single call through either period id or header id
*
From NT_CSRTNVPeriodInfo t
-- how can I make possible something like shown above, can I use a "Case When"?
Where ((#PeriodId IS NULL) or (t.PeriodId = #PeriodId))
And ((#HeaderId IS NULL) or (t.HeaderId = #HeaderId))
END
GO
You have to use conditional OR to check NULLs, if param is set, the second condition is checked, if not, the procedure will consider always true the statement and go to the next.
I'm writing some stored procedures in SQL Server 2008. Is the concept of optional input parameters possible here?
I suppose I could always pass in NULL for parameters I don't want to use, check the value in the stored procedure, and then take things from there, but I was interested if the concept is available here.
You can declare it like this:
CREATE PROCEDURE MyProcName
#Parameter1 INT = 1,
#Parameter2 VARCHAR (100) = 'StringValue',
#Parameter3 VARCHAR (100) = NULL
AS
/* Check for the NULL / default value (indicating nothing was passed) */
if (#Parameter3 IS NULL)
BEGIN
/* Whatever code you desire for a missing parameter */
INSERT INTO ........
END
/* And use it in the query as so */
SELECT *
FROM Table
WHERE Column = #Parameter
Yes, it is. Declare the parameter as so:
#Sort varchar(50) = NULL
Now you don't even have to pass the parameter in. It will default to NULL (or whatever you choose to default to).
In SQL Server 2014 and above at least, you can set a default, and it will take that and not error when you do not pass that parameter.
Partial example: the third parameter is added as optional. Execution (exec) of the actual procedure with only the first two parameters worked fine.
exec getlist 47,1,0
create procedure getlist
#convId int,
#SortOrder int,
#contestantsOnly bit = 0
as
The default mentioned in previous answers only works for simple cases. In more complicated cases, I use an IF clause near the beginning of the stored procedure to provide a value, if the parameter is NULL or empty and calculations are required.
I often use optional parameters in the WHERE clause, and discovered that SQL does not short circuit logic, so use a CASE statement to make sure not to try to evaluate NULL or empty dates or unique identifiers, like so:
CREATE Procedure ActivityReport
(
#FromDate varchar(50) = NULL,
#ToDate varchar(50) = NULL
)
AS
SET ARITHABORT ON
IF #ToDate IS NULL OR #ToDate = '' BEGIN
SET #ToDate = CONVERT(varchar, GETDATE(), 101)
END
SELECT ActivityDate, Details
FROM Activity
WHERE
1 = CASE
WHEN #FromDate IS NULL THEN 1
WHEN #FromDate = '' THEN 1
WHEN ActivityDate >= #FromDate AND ActivityDate < DATEADD(DD,1,#ToDate) THEN 1
ELSE 0
END