MySQL: Problems with procedure parameters - mysql

It seems something is wrong with my procedure. When I execute it, it should create an entry, directly modify a column and then return the id of it.
But nothing is created and it also returns nothing (not even an error is shown)
When I use hard coded values instead of using the parameters, the entry is created, but not edited and the ID is still not returned.
Could you guys have a look over it? This is the whole procedure result using the export function of phpMyAdmin:
CREATE DEFINER=`dbuser`#`localhost` PROCEDURE `createRecruitment`(IN `p_user_id` INT(11), IN `p_platform` ENUM('uplay','steam','ps4','xb1') CHARSET utf8, IN `p_activity` ENUM('pve','pvp') CHARSET utf8, IN `p_description` TEXT CHARSET utf8)
MODIFIES SQL DATA
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
DECLARE v_id INT(11);
INSERT INTO
recruitments (
user_id,
creationDate,
platform_id,
activity,
description
)
SELECT
p_user_id,
CURRENT_TIMESTAMP,
platforms.id,
p_activity,
p_description
FROM
platforms
WHERE
platforms.platform = p_platform;
SET v_id = LAST_INSERTED_ID();
UPDATE
recruitments
SET
lastActivity = creationDate
WHERE
id = v_id;
SELECT v_id;
END
EDIT
It seems the main problem is the "p_platform" parameter. I wanted to limit the input to the given ENUM but it seems the WHERE platforms.platform = p_platform doesn't work proper with this.

Use the below SP. I have use OUT v_id field and assign the value
CREATE DEFINER=`dbuser`#`localhost` PROCEDURE `createRecruitment`(IN `p_user_id` INT(11), IN `p_platform` ENUM('uplay','steam','ps4','xb1') CHARSET utf8, IN `p_activity` ENUM('pve','pvp') CHARSET utf8, IN `p_description` TEXT CHARSET utf8, OUT `v_id` INT(11))
MODIFIES SQL DATA
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
INSERT INTO
recruitments (
user_id,
creationDate,
platform_id,
activity,
description
)
SELECT
p_user_id,
CURRENT_TIMESTAMP,
platforms.id,
p_activity,
p_description
FROM
platforms
WHERE
platforms.platform = p_platform;
SET v_id = LAST_INSERTED_ID();
UPDATE
recruitments
SET
lastActivity = creationDate
WHERE
id = v_id;
END

Related

Create a table if given a procedure

I am trying to create a table in a database based on a procedure that was created. I am not to familiar with MySQL procedures to be able to try and create this database.
Here's the code for the procedure:
DELIMITER //
CREATE PROCEDURE SetChanProps(IN vchanmask TEXT, in vchankey TEXT, IN vcommentxt TEXT, IN ventrymsg TEXT, IN vexpires TIMESTAMP, IN vgroupname TEXT, IN vchanlimit INT, IN vmodes TEXT, IN vonlyowner INT, IN vsetbynick TEXT, IN vsetbyhost TEXT, IN vsetbypid INT, IN vtopic TEXT, IN vkickexisting INT)
BEGIN
DECLARE msgid int;
DECLARE rowcount int;
DECLARE setondate TIMESTAMP;
SET setondate = CURRENT_TIMESTAMP;
SELECT COUNT(*) INTO rowcount FROM `chanprops` WHERE `chanmask` = vchanmask;
if rowcount > 0 THEN UPDATE `chanprops` SET `chankey` = vchankey, `comment` = vcommentxt, `entrymsg` = ventrymsg, `expires` = vexpires, `groupname` = vgroupname, `limit` = vchanlimit, `mode` = vmodes, `onlyowner` = vonlyowner, `setbynick` = vsetbynick, `setbyhost` = vsetbyhost, `setbypid` = vsetbypid, `topic` = vtopic, `setondate` = setondate WHERE `chanmask` = vchanmask;
ELSE INSERT INTO `chanprops` (`chanmask`,`chankey`,`comment`,`entrymsg`,`expires`,`groupname`,`limit`,`mode`,`onlyowner`,`setbynick`,`setbyhost`,`setbypid`,`topic`) VALUES (vchanmask,vchankey,vcommentxt,ventrymsg,vexpires,vgroupname,vchanlimit,vmodes,vonlyowner,vsetbynick,vsetbyhost,vsetbypid,vtopic);
end if;
SET msgid = 36;
select matrixqueue(msgid,vchanmask,vchankey,vcommentxt,ventrymsg,Unix_Timestamp(vexpires),vgroupname,vchanlimit,vmodes,vonlyowner,vsetbynick,vsetbyhost,vsetbypid,vtopic,Unix_Timestamp(setondate),vkickexisting);
END//
DELIMITER ;
Is this the correct line to gather what I need to make this table?
ELSE INSERT INTO `chanprops` (`chanmask`,`chankey`,`comment`,`entrymsg`,`expires`,`groupname`,`limit`,`mode`,`onlyowner`,`setbynick`,`setbyhost`,`setbypid`,`topic`) VALUES (vchanmask,vchankey,vcommentxt,ventrymsg,vexpires,vgroupname,vchanlimit,vmodes,vonlyowner,vsetbynick,vsetbyhost,vsetbypid,vtopic);
Would I then use the CREATE PROCEDURE line (Line #2) to determine that types for the the column IDs?
Unfortunately, the project I am trying to utilize this procedure on hasn't been worked on in years and has been abandoned by its creator. They've included other .sql files that usually just create the tables for me. They seemed to have missed this one which conveniently is the one I really care about.

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.

Updating a table in my trigger fails

I am trying to update a table using an after insert trigger using this code
SET #OLDTMP_SQL_MODE=##SQL_MODE, SQL_MODE='STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
DELIMITER //
CREATE TRIGGER `le_log_trigger` AFTER INSERT ON `messagelog` FOR EACH ROW BEGIN
declare last_inserted_number VARCHAR(100) DEFAULT '0800100200';
declare last_inserted_code VARCHAR(100) DEFAULT 'Lorem Ipsum';
declare current_dataset VARCHAR(100) DEFAULT 'Lorem Ipsum';
set last_inserted_number = NEW.messagefrom;
set last_inserted_code = NEW.statuscode;
set current_dataset = (select task_name from running_tasks limit 1);
if(last_inserted_code = 201) then
update current_dataset set the_status = 'online' where device_number = last_inserted_number;
end if;
END//
DELIMITER ;
My database is called logan and i get this error when the trigger runs
/* SQL Error (1146): Table 'logan.current_dataset' doesn't exist */
Why is current_dataset not being treated as a variable?.
Because you're trying to do an UPDATE query. MySQL expects to see a table name where you've got your variable, so it won't go "oh, hey, this was declared as a variable earlier". It'll just assume right away that it's supposed to be a literal table name, and look for that table... and since it can't be found (because it doesn't exist), you get that error.
If you DID by chance have a table where a field name did co-incide with a variable name, eg.
table x (foo int, bar int);
set bar='baz';
and did
UPDATE x SET foo=bar
then you've got a problem. Which bar should be used? Are you referring the variable, or to the field? That's why there's #:
UPDATE x SET foo=bar ; // use "bar" field in the table
UPDATE x SET foo=#bar; // use variable "bar" value.
And note that you couldn't use the variable as a table name, e.g.
SET x = 'tablename';
UPDATE #x SET ...
is just a flat-out syntax error. You'd have to build a query string inside your sproc, and then prepare/execute it.

Mysql UDF to return record id if exists else insert and return recordid`

I am trying to write a Mysql Function to return a contactID if the record exists based on the parameters supplied, If the record is not present, I am adding the record and then returning the contactID of the new record.
But the function is throwing 1048error, Can you check and correct me if I went wrong in writing this.
DELIMITER $$
CREATE DEFINER=`root`#`%` FUNCTION `GetContactID`(accountNumber CHAR(45),UserID INT(11)) RETURNS char(1) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE ContactID INT DEFAULT 0;
SELECT ContactID INTO #ContactID FROM Contact WHERE AccountNumber = #accountNumber AND UserID = #UserID AND Status =1;
IF ContactID = 0 or ContactID is null THEN
INSERT INTO Contact(AccountNumber,UserID) VALUES (#accountNumber,#UserID);
SELECT ContactID INTO #ContactID FROM Contact WHERE AccountNumber = #accountNumber AND UserID = #UserID;
END IF;
RETURN ContactID;
END
Can someone help me where I went wrong.
Thanks
The problem results from mixing user variables, local variables and parameters.
#UserId is not the same as UserId - they are different variables.
UserId is also a name of column in the table.
User defined variables are wirtten as #var_name, are stored in the user session and can be used to pass values between differend stored routines that reference them, see this link for details: http://dev.mysql.com/doc/refman/5.7/en/user-variables.html
local variables are declared in stored routines using DECLARE keyword, their scope is local within the stored routine, see this link for details: http://dev.mysql.com/doc/refman/5.7/en/declare-local-variable.html
Parameters of function/procedure - they are declared in the procedure/function declaration, they are used to pass parameters to the stored routine from the caller, can be also used to return results from the routine to the caller (if declared as OUT or INOUT). Their scope is similar to local variables. For details see this link: http://dev.mysql.com/doc/refman/5.7/en/create-procedure.html
Try this code:
DELIMITER $$
CREATE DEFINER=`root`#`%` FUNCTION `GetContactID`(p_accountNumber CHAR(45),p_UserID INT(11)) RETURNS char(1) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE v_ContactID INT DEFAULT 0;
SELECT ContactID INTO v_ContactID
FROM Contact
WHERE AccountNumber = p_accountNumber AND UserID = p_UserID AND Status =1;
IF v_ContactID = 0 or v_ContactID is null THEN
INSERT INTO Contact(AccountNumber,UserID)
VALUES (p_accountNumber,p_UserID);
SELECT ContactID INTO v_ContactID FROM Contact
WHERE AccountNumber = p_accountNumber AND UserID = p_UserID;
END IF;
RETURN v_ContactID;
END;
Notice that:
function parameters are declared with prefix p_
local variables are declared with prefix v_
the function doesn't use any user variables (prefixed by #)
These prefixes help to avoid ambiguity - we know that p_UserID is a parameter, v_UserId is a local variable, and UserID is a column name in the table (If we would use #UserId, we knew that this was the user variable).

SSRS Pivot Expression Inside Stored Procedure with HashTemp Not Running

While Working With SSRS, Today, i got 2 Problems 1 is Still remain Unsolved and Im going to Post Another Freaking Problem :) Well, Problem is : I've an Stored Procedure, Which Create an #Temp and Finally Use that data with PIVOT Expression. And, Stored Procedure itself runs Fine inside SSMS and From Visual Basic 6.0 too, but While Using that Procedure from SSRS report it shows an error at the Pivot Expression. Following are the Screen Shots, Please Review and Suggest me an Idea.
Here is an Stored Procedure :
ALTER PROCEDURE [dbo].[S_NRB_9_8_REPORT](#SCRCODE AS VARCHAR(20),
#CUREDATE VARCHAR(10),
#DTNAME VARCHAR(50),
#BR_CODE VARCHAR(50),
#CENTRALIZED VARCHAR(3))
WITH RECOMPILE
AS BEGIN
SET NOCOUNT ON;
DECLARE #BRCODE VARCHAR(3)
DECLARE #DTBASE VARCHAR(50)
DECLARE #CAT_TYPE_CODE VARCHAR(50)
DECLARE #AC_TYPE_SUB_TYPE_NAME VARCHAR(200)
DECLARE #CODESTR VARCHAR (1000)
DECLARE #CODESTR1 VARCHAR (1000)
SET #BRCODE=''
SET #DTBASE=''
SET #AC_TYPE_SUB_TYPE_NAME=''
SET #CODESTR=''
SET #CODESTR1=''
SELECT TOP 1 #CAT_TYPE_CODE=CAT_TYPE_CODE FROM REPORT_CAT_TYPE_CODE WHERE SCREEN_CODE =#SCRCODE
IF #CAT_TYPE_CODE='' OR #CAT_TYPE_CODE IS NULL
RETURN
CREATE TABLE [dbo].[#TEMPACTYPE](
[BR_CODE] [varchar](3) NULL,
[CN] [varchar](50) NULL,
[CS] [varchar](50) NULL,
[BAL] decimal(18, 2) NULL,
[AC_TYPE_SUB_TYPE_NAME] [varchar](50) NULL
) ON [PRIMARY]
IF LEN(#BR_CODE)>0
EXEC('DECLARE CUR INSENSITIVE CURSOR FOR SELECT BR_CODE FROM '+#DTBASE+'.DBO.BRANCH B (NOLOCK) WHERE BR_CODE='''+#BR_CODE+''' AND INTEGRATED=''YES'' AND APPROVED=''YES'' ORDER BY BR_CODE')
ELSE
EXEC('DECLARE CUR INSENSITIVE CURSOR FOR SELECT BR_CODE FROM '+#DTBASE+'.DBO.BRANCH B (NOLOCK) WHERE INTEGRATED=''YES'' AND APPROVED=''YES'' ORDER BY BR_CODE')
OPEN CUR
FETCH NEXT FROM CUR INTO #BRCODE
While ##FETCH_STATUS = 0
Begin
IF #CENTRALIZED='YES'
SET #DTBASE = #DTNAME
ELSE
SET #DTBASE = Left(#DTNAME, 13) + #BRCODE
EXEC('INSERT INTO #TEMPACTYPE
SELECT '''+#BRCODE+''' AS BR_CODE,T1.CAT_NAME AS CN,T1.CODES AS CS,SUM(T1.C_BAL)AS BAL,T1.AC_TYPE_SUB_TYPE_NAME FROM
(SELECT C_BAL,ATST.AC_TYPE_SUB_TYPE_NAME,CD.CAT_NAME,CD.CODE_STRING AS CODES
FROM
(SELECT AC_GROUP_CODE,CUR_CODE,GL_CODE FROM '+#DTBASE+'.dbo.AC_GROUP_GL_MAP WHERE NAMED_AC_CODE =''0301'') MAP,
(SELECT AC_GROUP_CODE,CUR_CODE,AC_NO FROM '+#DTBASE+'.dbo.DEPOSIT_AC_MAST WHERE BR_CODE='''+#BRCODE+''') DAM,
(SELECT TRAN_DATE,AC_NO,GL_CODE,PRODUCT_CODE,SUM(CLS_BAL) AS C_BAL FROM '+#DTBASE+'.dbo.AC_BAL WHERE BR_CODE='''+#BRCODE+''' GROUP BY TRAN_DATE,AC_NO,GL_CODE,PRODUCT_CODE) WD,
(SELECT * FROM '+#DTBASE+'.dbo.CAT_CODING where BR_CODE='''+#BRCODE+''' AND CAT_TYPE_CODE ='''+#CAT_TYPE_CODE+''') AS CC,
(SELECT * FROM '+#DTBASE+'.dbo.AC_TYPE_SUB_TYPE) AS ATST,
(SELECT * FROM '+#DTBASE+'.dbo.AC_GROUP) AS AG,
(SELECT * FROM '+#DTBASE+'.dbo.CAT_DETL) AS CD
WHERE
DAM.AC_GROUP_CODE =MAP.AC_GROUP_CODE
AND DAM.CUR_CODE =MAP.CUR_CODE
AND WD.GL_CODE =MAP.GL_CODE
AND CC.ENTITY_NO=DAM.AC_NO
AND ATST.AC_TYPE_CODE=AG.AC_TYPE_CODE
AND ATST.AC_TYPE_SUB_TYPE_CODE=AG.AC_TYPE_SUB_TYPE_CODE
AND AG.AC_GROUP_CODE=DAM.AC_GROUP_CODE
AND CD.CAT_TYPE_CODE=CC.CAT_TYPE_CODE
AND CD.CAT_CODE=CC.CAT_CODE
AND CD.CAT_TYPE_CODE='''+#CAT_TYPE_CODE+'''
AND WD.TRAN_DATE = (SELECT MAX(TRAN_DATE) FROM '+#DTBASE+'.dbo.AC_BAL WHERE BR_CODE ='''+#BRCODE+''' AND AC_NO = DAM.AC_NO AND TRAN_DATE <='''+#CUREDATE+''' AND GL_CODE=MAP.GL_CODE)
AND DAM.AC_NO=WD.AC_NO
UNION ALL
SELECT 0,ATST.AC_TYPE_SUB_TYPE_NAME,CAT_NAME,CODE_STRING AS CODES FROM '+#DTBASE+'.dbo.CAT_DETL AS CD,'+#DTBASE+'.dbo.AC_TYPE_SUB_TYPE AS ATST
WHERE CAT_TYPE_CODE='''+#CAT_TYPE_CODE+''' AND CAT_CODE NOT IN (SELECT CAT_CODE FROM '+#DTBASE+'.dbo.CAT_CODING WHERE BR_CODE='''+#BRCODE+''' AND CAT_TYPE_CODE='''+#CAT_TYPE_CODE+''')
AND ATST.AC_TYPE_CODE=''03''
) T1
GROUP BY T1.AC_TYPE_SUB_TYPE_NAME,CAT_NAME,CODES
ORDER BY CODES
')
FETCH NEXT FROM CUR INTO #BRCODE
END
DEALLOCATE CUR
DECLARE CUR INSENSITIVE CURSOR FOR SELECT DISTINCT AC_TYPE_SUB_TYPE_NAME FROM #TEMPACTYPE
OPEN CUR
Fetch Next from CUR Into #AC_TYPE_SUB_TYPE_NAME
While ##FETCH_STATUS = 0
Begin
IF #CODESTR =''
BEGIN
SET #CODESTR = 'ISNULL(['+#AC_TYPE_SUB_TYPE_NAME+'],0) AS ['+#AC_TYPE_SUB_TYPE_NAME+']'
SET #CODESTR1 = '['+#AC_TYPE_SUB_TYPE_NAME+']'
END
ELSE
BEGIN
SET #CODESTR = #CODESTR+',ISNULL(['+#AC_TYPE_SUB_TYPE_NAME+'],0) AS ['+#AC_TYPE_SUB_TYPE_NAME+']'
SET #CODESTR1 = #CODESTR1+',['+#AC_TYPE_SUB_TYPE_NAME+']'
END
Fetch Next from CUR Into #AC_TYPE_SUB_TYPE_NAME
END
DEALLOCATE CUR
EXEC ('Select CS,CN,'+#CODESTR+',TOTAL
from (Select CN,CS,BAL,[AC_TYPE_SUB_TYPE_NAME] from #TEMPACTYPE) ps pivot (SUM([BAL])
for [AC_TYPE_SUB_TYPE_NAME] in ('+#CODESTR1+',TOTAL)) pvt
Order by CS')
DROP TABLE #TEMPACTYPE
END
GO
And, the Dataset Design Panel :
But, Stored Procedure Runs Well inside SSMS :
Im Using SSRS 2008 R2.
Please Help me out.
And, Thanks In Advance.
Try validating that you are passing the same parameter values between the report and SSMS. You can do this by clicking Edit Query and inputting the actual parameter values. If the Edit Query window returns proper results, then you are probably passing different values to the stored procedure.