Problem in returning values with my procedure - mysql

The following procedure is not returning values. Whats wrong?
CREATE PROCEDURE `sp_ValidarLogin`
(pEmail VARCHAR(45),
pSenha VARCHAR(255),
OUT rId INT,
OUT rNome VARCHAR(45),
OUT rDataNascimento DATE)
SELECT #rId = ID,
#rNome = NOME,
#rDataNascimento = DATA_NASCIMENTO
FROM usuario
WHERE EMAIL = pEmail AND SENHA = pSenha;
CALL sp_ValidarLogin ('rcaldas.ti#gmail.com','1234', #id, #nome, #nascimento);--its correct
select #id, #nome, #nascimento;

You have to use := instead of = to assign values on SELECT:
CREATE PROCEDURE `sp_ValidarLogin` (
pEmail VARCHAR(45),
pSenha VARCHAR(255),
OUT rId INT,
OUT rNome VARCHAR(45),
OUT rDataNascimento DATE)
SELECT #rId := ID, #rNome := NOME, #rDataNascimento := DATA_NASCIMENTO
FROM usuario
WHERE EMAIL = pEmail AND SENHA = pSenha;
demo on dbfiddle.uk
Previous releases of MySQL made it possible to assign a value to a user variable in statements other than SET. This functionality is supported in MySQL 8.0 for backward compatibility but is subject to removal in a future release of MySQL.
When making an assignment in this way, you must use := as the assignment operator; = is treated as the comparison operator in statements other than SET.
source: https://dev.mysql.com/doc/refman/8.0/en/user-variables.html

Related

Get String between two strings - SQL Server

I got a function that returns string between two strings:
CREATE FUNCTION dbo.udf_GetStringBetween2Chars (#String VARCHAR(50), #FirstSpecialChar VARCHAR(50), #LastSpecialChar VARCHAR(50))
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE #FirstIndexOfChar INT,
#LastIndexOfChar INT,
#LengthOfStringBetweenChars INT
SET #FirstIndexOfChar = CHARINDEX(#FirstSpecialChar,#String,0)
SET #LastIndexOfChar = CHARINDEX(#LastSpecialChar,#String,#FirstIndexOfChar+1)
SET #LengthOfStringBetweenChars = #LastIndexOfChar - #FirstIndexOfChar -1
SET #String = SUBSTRING(#String,#FirstIndexOfChar+1,#LengthOfStringBetweenChars)
RETURN #String
END
However, when I try to get string between POINTDESCRIPTION and DATAPOINT, I get error:
SET ANSI_WARNINGS OFF
declare #table table
(string varchar(50))
insert into #table
select 'EVENT: ID Order Reassignment (Individual Job Specific Update)|||LOCATION: Reassign.reassign()|||DATEPOINTDESCRIPTION: Only specific ID orders were reassigned from user fatis to user blake.|||DATAPOINT: blake' union all
select 'EVENT: ID Order Reassignment (Individual Job Specific Update)|||LOCATION: Reassign.reassign()|||DATAPOINTDESCRIPTION: Only specific ID orders were reassigned from user ilevic to user manic2.|||DATAPOINT: manic2' union all
select 'EVENT: ID Order Reassignment (Individual Job Specific Update)|||LOCATION: Reassign.reassign()|||DATAPOINTDESCRIPTION: Only specific ID orders were reassigned from user links to user sepir.|||DATAPOINT: sepir'
select dbo.udf_GetStringBetween2Chars (Tab.string,'POINTDESCRIPTION: ','|||DATAPOINT')
FROM #table Tab
Msg 537, Level 16, State 2, Line 10
Invalid length parameter passed to the LEFT or SUBSTRING function.
Does anyone see why this would happen?
If anyone finds it useful, here is final function to return string between 2 strings:
CREATE FUNCTION dbo.udf_GetStringBetween2Chars (#String VARCHAR(500), #FirstSpecialChar VARCHAR(500), #LastSpecialChar VARCHAR(500))
RETURNS VARCHAR(500)
AS
BEGIN
DECLARE #FirstIndexOfChar INT,
#LastIndexOfChar INT,
#LengthOfStringBetweenChars INT
SET #FirstIndexOfChar = CHARINDEX(#FirstSpecialChar,#String,0)
SET #LastIndexOfChar = CHARINDEX(#LastSpecialChar,#String,#FirstIndexOfChar+1)
SET #LengthOfStringBetweenChars = #LastIndexOfChar - #FirstIndexOfChar -1
SET #String = SUBSTRING(#String,#FirstIndexOfChar+LEN(#FirstSpecialChar),#LengthOfStringBetweenChars)
RETURN #String
END
GO
And to call it:
select dbo.udf_GetStringBetween2Chars (tab.someString,'POINTDESCRIPTION: ','|||DATAPOINT')
FROM yourTable tab

Mysql Stored Proc not returning a VARCHAR out parameter

Below is my stored procedure. It works fine but my problem is I can't get the output parameter as VARCHAR.
The part where I'm having problem is the assignment of #curcName to the out parameter op_resultMessage
BEGIN
SET op_resultMessage = #curcName;
END;
Here's the Stored Procedure.
CREATE DEFINER=`root`#`localhost` PROCEDURE `addCurriculum`(
IN p_curcName varchar(100),
IN p_description TEXT,
IN p_yearLevel VARCHAR(50),
IN p_syStart INT,
IN p_syEnd INT,
IN p_creator VARCHAR(50),
OUT op_resultMessage VARCHAR(50))
BEGIN
DECLARE curcName VARCHAR(20) ;
IF EXISTS
(SELECT #curcName := `name`
FROM curriculum
WHERE
yearLevel = p_yearLevel
AND syStart = p_syStart
AND syEnd = p_syEnd )
THEN --
BEGIN
SET op_resultMessage = #curcName;
END;
ELSE
BEGIN
INSERT INTO curriculum(`name`, description, yearLevel, syStart, syEnd, creator)
VALUES(p_curcName,p_description,p_yearLevel,p_syStart,p_syEnd,p_creator);
END;
END IF;
END
I'm trying to return a message IF name EXISTS
So it should go something like
SET op_resultMessage = #curcName 'already uses the school year and year level you're trying to insert';
But I don't know how to properly concatenate and assign values. I'm still confused with := SET and = operators. I guess that's where I'm having problems with.
If I change the out parameter's type to an INT like
OUT op_resultMessage VARCHAR(50)
then assigns a number to op_resultMessage like SET op_resultMessage = 1;
It returns the number 1 as out parameter values. It just won't work with varchar.
So when I try to call the procedure
CALL `enrollmentdb`.`addCurriculum`
('Test Curriculum ','Test ','Grade 1',2015,2016,'jordan',#outputMsg);
SELECT #outputMsg; -- this doesn't return any value even if Grade 1, 2015 and 2016 exists
I'd appreciate any help. I actually just learned mysql recently.
Thanks.
drop procedure if exists addCurriculum;
delimiter $$
CREATE PROCEDURE `addCurriculum`(
IN p_curcName varchar(100),
IN p_description TEXT,
IN p_yearLevel VARCHAR(50),
IN p_syStart INT,
IN p_syEnd INT,
IN p_creator VARCHAR(50),
OUT op_resultMessage VARCHAR(50))
BEGIN
DECLARE curcName VARCHAR(20) ;
SELECT `name` into #curcName
FROM curriculum
WHERE
yearLevel = p_yearLevel
AND syStart = p_syStart
AND syEnd = p_syEnd
LIMIT 1;
-- Note change above. When selecting into a variable (or more than 1)
-- then 0 or 1 rows can come back max or an Error occurs
IF #curcName is not null then
SET op_resultMessage = #curcName;
ELSE
BEGIN
INSERT INTO curriculum(`name`, description, yearLevel, syStart, syEnd, creator)
VALUES(p_curcName,p_description,p_yearLevel,p_syStart,p_syEnd,p_creator);
END;
SET op_resultMessage = 'GEEZ I am right here'; -- Drew added this
END IF;
END$$
delimiter ;
Note the commentary in the stored procedure, especially the part of only 0 or 1 rows returning else an Error will occur with a select into var pattern. So LIMIT 1. That may or may not be the row you want (limit 1), but that is where it is at right now.

MySQL LIKE keyword not returning expected result

I have a stored procedure that I used with a search function I created. The query within the procedure is as follows:
CREATE DEFINER=`root`#`localhost` PROCEDURE `advanced_search`(IN major_name VARCHAR(45),
OUT major_code INT, IN classification VARCHAR(45), IN job_class VARCHAR(45))
BEGIN
SELECT major_id INTO major_code FROM major
WHERE major = major_name;
SET #classification = classification;
SELECT * FROM job WHERE (major = major_code) OR (classification LIKE '%#classification%') OR (job_type = job_class);
END
I am having a problem with LIKE keyword clause. I want to check if a value in the classification field contains or includes the #classification variable. For some reason when I single out the clause that uses that keyword (by removing the first and third clause in the WHERE statement) it does not return anything.
Is there any advice on how to fix this?
Also, is it common for the object that appears below to be found within the results object?
{
"fieldCount": 0,
"affectedRows": 0,
"insertId": 0,
"serverStatus": 34,
"warningCount": 0,
"message": "",
"protocol41": true,
"changedRows": 0
}
EDIT: Here is the query I call
set #major_name = 'Chemical Engineering';
set #major_code = 0;
set #classification = 'Freshman';
set #job_class = 'Assistant';
call aggie_soop.advanced_search(#major_name, #major_code, #classification, #job_class);
These are the results. This is the exact same as the original table
I don't think you need a user-defined variable, you can reference the procedure argument.
You can use the MySQL CONCAT() function to concatenate the percent sign literals with the value.
I prefer to qualify all column references, and use a naming convention for procedure variables that avoids name collisions. While MySQL doesn't care, it makes it much easier for the future reader to decipher the intent.
CREATE DEFINER=`root`#`localhost`
PROCEDURE `advanced_search`
( IN p_major_name VARCHAR(45)
, OUT p_major_code INT
, IN p_classification VARCHAR(45)
, IN p_job_clas VARCHAR(45)
)
BEGIN
SELECT m.major_id INTO p_major_code
FROM major m
WHERE m.major = p_major_name
LIMIT 1
;
SELECT j.*
FROM job j
WHERE (j.major = p_major_code)
OR (j.classification LIKE CONCAT('%',p_classification,'%')
OR (j.job_type = p_job_class)
;
END
(I believe it's possible to "read" the value of the OUT parameter within the procedure, but I've never done it before.)
Note that if the p_classification string is a zero length string, then every row with a non-NULL value in the classification column is going to be returned.
You may want something like this:
OR (p_classification <> '' AND j.classification LIKE CONCAT('%',p_classification,'%')
(But the specification isn't clear.)
A small change is needed:
CREATE DEFINER=`root`#`localhost` PROCEDURE `advanced_search`(IN major_name VARCHAR(45),
OUT major_code INT, IN classification VARCHAR(45), IN job_class VARCHAR(45))
BEGIN
SELECT major_id INTO major_code FROM major
WHERE major = major_name;
SET #classification = classification;
SELECT * FROM job WHERE (major = major_code) OR (classification LIKE '%' || #classification || '%') OR (job_type = job_class);
END

How to fix error in procedure SQL?

there is a hranimka, when it was created, an error occurs. Maybe she who struck by the ...
The stored procedure:
CREATE PROCEDURE insert_log(
IN LogType INT,
IN LogIdNote INT,
IN LogName VARCHAR,
IN LogTime TIMESTAMP,
IN logTypeCategory INT,
IN LogIdUser INT)
begin
INSERT INTO log (LogType,
LogIdNote,
LogName,
LogTime,
logTypeCategory,
LogIdUser,
LogTypeUser,
LogUrl)
SELECT LogType, LogIdNote, LogName, LogTime, logTypeCategory, LogIdUser, url.URLCategorysubscribetotype, u.UsersTypeAccount FROM users u LEFT JOIN categorysubscribetotype url ON url.CategoryTypeCategorysubscribetotype = LogType WHERE u.idUsers = LogIdUser;
end //
Error:
1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'INT LogType, INT LogIdNote, VARCHAR LogName, TIMESTAMP LogTime,
I' at line 3
I tried only change data types at params.
I think, the next code will give me a good result, but I need save result from SELECT query at variable and insert it at query Insert:
DELIMITER |
CREATE PROCEDURE insert_log(
IN pLogType INT,
IN pLogIdNote INT,
IN pLogName VARCHAR(150),
IN pLogTime TIMESTAMP,
IN plogTypeCategory INT,
IN pLogIdUser INT)
BEGIN
DECLARE user_type INT DEFAULT 0;
DECLARE url VARCHAR(250) DEFAULT;
SET user_type = (SELECT UsersTypeAccount FROM users WHERE idUsers = pLogIdUser);
SET url = (SELECT URLCategorysubscribetotype FROM categorysubscribetotype WHERE CategoryTypeCategorysubscribetotype = pLogType);
INSERT INTO log (pLogType,
pLogIdNote,
pLogName,
pLogTime,
plogTypeCategory,
pLogIdUser,
pLogTypeUser,
pLogUrl)
VALUES (
LogType,
LogIdNote,
LogName,
LogTime,
logTypeCategory,
LogIdUser,
user_type,
url
);
END |
delimiter ;
Your issue is here:
INSERT INTO log (pLogType, //wrong!
pLogIdNote,
pLogName,
pLogTime,
plogTypeCategory,
pLogIdUser,
pLogTypeUser,
pLogUrl)
You have used the parameter as column while they should be VALUES try this Query
DELIMITER //
CREATE PROCEDURE insert_log(
IN pLogType INT,
IN pLogIdNote INT,
IN pLogName VARCHAR(150),
IN pLogTime TIMESTAMP,
IN plogTypeCategory INT,
IN pLogIdUser INT)
BEGIN
DECLARE user_type INT DEFAULT 0;
DECLARE url VARCHAR(250) DEFAULT;
SET user_type = (
SELECT UsersTypeAccount
FROM users
WHERE idUsers = pLogIdUser
);
SET url = (
SELECT URLCategorysubscribetotype
FROM categorysubscribetotype
WHERE CategoryTypeCategorysubscribetotype = pLogType
);
INSERT INTO log (
`LogType`,
`LogIdNote`,
`LogName`,
`LogTime`,
`logTypeCategory`,
`LogIdUser`,
`LogIdUserType`, /*I added this*/
`LogIdUrl`, /*this one too */
)VALUES (
pLogType,
pLogIdNote,
pLogName,
pLogTime,
plogTypeCategory,
pLogIdUser,
user_type,
url
);
END //
DELIMITER ;
Please note You need to adjust this stored procedure, there was few mistakes. for example pLogTypeUser and pLogUrl are undefined and I added comments where you need to change the column name.
Your syntax is wrong. The data types come after the parameter names, the IN/OUT specifiers come before. Something like this:
CREATE PROCEDURE insert_log(
IN LogType INT,
IN LogIdNote INT,
IN LogName VARCHAR(10),
IN LogTime TIMESTAMP,
IN logTypeCategory INT,
IN LogIdUser INT)
begin
...
Edit: Also note that I added a size specifier to the VARCHAR data type, since it requires one. I guessed at 10, but you can replace that value with whatever yours is.

mysql optional variables function

So say I have a user defined function:
CREATE FUNCTION ADDRESS_EXISTS_FULL (
line_1 VARCHAR(64),
line_2 VARCHAR(64),
city VARCHAR(64),
state VARCHAR(32),
zip VARCHAR(10),
type INT(3)
)
RETURNS INT(1)
DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE aid INT;
SET aid = NULL;
SELECT addressid INTO aid FROM dlp.address as a
WHERE a.line_1 = line_1
AND a.line_2 = line_2
AND a.city = city
AND a.state = state
AND a.zip = zip
AND a.address_type = type
LIMIT 1;
RETURN IF(aid IS NOT NULL, 1, 0);
END$$
How do I make it so that some of these are not necessary? Like say if type is not needed, is there anyway to call
SELECT ADDRESS_EXISTS_FULL(l1,l2,c, s, z)
or would that fail? And how do I make that function work?
Thanks.
Note: I don't need this function stored, it's a one off so it's in one big mysql script file.
You can rewrite the query inside stored function body to something like
SELECT addressid INTO aid FROM dlp.address as a
WHERE (a.line_1 = p_line_1 OR p_line_1 IS NULL)
AND (a.line_2 = p_line_2 OR p_line_2 IS NULL)
--.... etc
LIMIT 1;
Thus, if you pass null for a particular parameter, it will be ignored. Also, I'd recommend avoiding naming parameters exactly the same as fields in the table - it may lead to very subtle bugs (In the query above I prepended 'p_' to each parameter).
Finally, I'd not use DETERMINISTIC keyword for a function that is non-deterministic by nature.