DELIMITER //
CREATE OR REPLACE PROCEDURE GET_USER_PNTS(USER_ID INT , PNTS INT, QNT INT)
BEGIN
DECLARE x INT DEFAULT 1;
DECLARE TEMP_GIFT_ID INT;
UPDATE USR_PNT_SUMM SET USD_PNTS = USD_PNTS + PNTS WHERE USER_ID = 1;
COMMIT;
END //
DELIMITER ;
The above stored procedure updates two rows - one for user_id = 1 and the other one for userid 0. I dont understand why!
This is how I call the stored procedure -
CALL GET_USER_PNTS(1, 1, 1)
Please let me know why the user_id 0 is also getting updated.
P.S
1. I am using MariaDB.
2. UserID 0 is what I had manually added in the table. In pratice there won't be any 0 user_id. But even then, the row should not have been updated.
Please rename your parameters:
CREATE OR REPLACE PROCEDURE GET_USER_PNTS(L_USER_ID INT , L_PNTS INT, L_QNT INT)
BEGIN
DECLARE x INT DEFAULT 1;
DECLARE TEMP_GIFT_ID INT;
UPDATE USR_PNT_SUMM SET USD_PNTS = USD_PNTS + L_PNTS WHERE USER_ID = L_USER_ID;
COMMIT;
END //
Probably USER_ID = USER_ID is treated as true.
Related
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.
I cant get this code to return me anything, i used to have the code in 2 functions and it always returned a random first name and a random last name but ever since i tried putting the code into this procedure it doesnt return anything, either empty results or just nothing happens after submitting the CALL command
DROP PROCEDURE IF EXISTS IdGenerator;
DELIMITER $$
CREATE PROCEDURE IdGenerator(tempCntry varchar(255))
BEGIN
DECLARE rndm1 INT;
DECLARE rndm2 INT;
DECLARE rndmPlier INT;
DECLARE firstN varchar(255);
DECLARE lastN varchar(255);
DROP TABLE IF EXISTS pplGrp;
CREATE TEMPORARY TABLE pplGrp(FirstName_tmp varchar(255), LastName_tmp varchar(255));
SELECT MAX(ChancesEnd) INTO rndmPlier FROM personlist WHERE country = tempCntry;
SET rndm1 = FLOOR((1+RAND() * (rndmPlier-1)));
SELECT p.name INTO firstN FROM personlist p WHERE country = tempCntry AND FirstName = 1 AND sex = 0 AND p.ChancesStart <= rndm1 AND p.ChancesEnd >= rndm1 LIMIT 1;
SET rndm2 = FLOOR((1+RAND() * (rndmPlier-1)));
SELECT p.name INTO lastN FROM personlist p WHERE country = tempCntry AND LastName = 1 AND sex = 0 AND p.ChancesStart <= rndm2 AND p.ChancesEnd >= rndm2 LIMIT 1;
INSERT INTO pplGrp (FirstName_tmp, LastName_tmp)values(firstN, lastN);
SELECT * FROM pplGrp;
END$$
DELIMITER ;
I have a function in mysql like below:
DELIMITER $$
CREATE DEFINER=root#localhost FUNCTION fnGetDropDownValue(
itemValue varchar(300),
DropDownId int,
CId int
) RETURNS int(11)
BEGIN
DECLARE listId int;
SELECT ListID into listId FROM DropDownListValues WHERE LOWER(ListValue) = LOWER(itemValue) AND DropDownListID = DropDownId AND (ClientId = 0 OR ClientId = CId);
RETURN listId;
END$$
But it always returns Null values when I use
SELECT fnGetDropDownValue('General', 24, 18);
I don't know what I am doing wrong :(
After having the case sensitive issue with mysql columns I used to have variable names to start with _ to avoid it messing with column names. Now the stored procedure looks like this:
DELIMITER $$
CREATE DEFINER=root#localhost FUNCTION fnGetDropDownValue(
itemValue varchar(300),
DropDownId int,
CId int
) RETURNS int(11)
BEGIN
DECLARE _listId int;
SELECT ListID into _listId FROM DropDownListValues WHERE LOWER(ListValue) = LOWER(itemValue)
AND DropDownListID = DropDownId AND (ClientId = 0 OR ClientId = CId);
RETURN _listId;
END$$
This way it will work on any platform and it may be useful for others.
I have some troubles with DECLARE, CALL function and a IF settelment. What i have so far is:
CREATE PROCEDURE number_of_projects(project_name VARCHAR)
BEGIN
DECLARE variable INT;
SET variable = 4;
SELECT variable;
SELECT count(project_id) FROM atm_projects WHERE project_name = variable;
END
IF number_of_projects("PROJECT NAME") = 0
THEN
INSERT INTO atm_projects(project_id,project_name,added_from_mti)
VALUES (project_id,'PROJECT NAME',1)
ENDIF
The main goal is to insert a row into a table where project_name is not duplicated.
I could change project_name to an UNIQUE key but please tell me what is wrong with my code, an how can i fix this?
I need to learn how a PROCEDURE, CALL procedure, IF works.
try:
CREATE PROCEDURE number_of_projects(project_name VARCHAR(255))
BEGIN
DECLARE var_project_no INT;
SET var_project_no = 0;
SELECT var_project_no;
SELECT count(project_id) INTO var_project_no FROM atm_projects WHERE var_project_name = 4;
IF var_project_no = 0
THEN
INSERT INTO atm_projects(project_id,project_name,added_from_mti)
VALUES (project_id,'PROJECT NAME',1)
END IF;
END;
You have declared project_name to varchar without specifying the length. Change it to varchar(100)
CREATE PROCEDURE number_of_projects(project_name VARCHAR(255))
BEGIN
if NOT exists(SELECT Top 1 1 FROM atm_projects WHERE var_project_name = 4)
BEGIN
INSERT INTO atm_projects(project_id,project_name,added_from_mti)
Select project_id,project_name ,1
END
END;
I have a table which contains header information for transactions. The transactions belong to different projects.
In the header I have columns:
rhguid - uniqueidentifier
rhserial - int
rh_projectID - int
First I insert the row (there's more columns)
Then I calculate the serial number for that project:
update responseheader
set rhSerial = 1 + (select isnull(max(rhSerial), 0)
from responseheader
where (rhstatus = 0) AND (rh_projectID = 1234))
where
(rhGUID = <preassignedGUID>);
However when there are many transactions happening at the same time for a project I am finding duplicate rhserial values.
I'm doing this in classic ASP with SQL Server 2008.
Is there a better way?
From your example, it doesn't look like you're using a transaction. My guess is that the SELECT portion of the statement is running as READ UNCOMMITTED, otherwise you would not see duplicates. There are ways to start transactions with ADO, but I prefer using stored procedures instead.
Try implementing something like this:
CREATE PROC dbo.ResponseHeader_Insert
<more data to insert>,
#ProjectID INT,
#Status SMALLINT
as
insert responseheader (column names here)
select <param values here>, isnull(max(rhSerial), 0) + 1
from responseheader
where (rhstatus = #Status) AND (rh_projectID = #ProjectID))
If this doesn't work for ya, try creating sequence tables (one for each sequence).
create table <tablename> (
SeqID int identity(1,1) primary key,
SeqVal varchar(1)
)
Create a procedure to get the next identity:
create procedure GetNewSeqVal_<tablename>
as
begin
declare #NewSeqValue int
set NOCOUNT ON
insert into <tablename> (SeqVal) values ('a')
set #NewSeqValue = scope_identity()
delete from <tablename> WITH (READPAST)
return #NewSeqValue
end
If there are too many sequence tables that need to be created or you want to create sequences on the fly, try this approach:
Create table AllSequences (
SeqName nvarchar(255) primary key, -- name of the sequence
Seed int not null default(1), -- seed value
Incr int not null default(1), -- incremental
Currval int
)
Go
create procedure usp_CreateNewSeq
#SeqName nvarchar(255),
#seed int = 0,
#incr int = 1
as
begin
declare #currval int
if exists (
select 1 from AllSequences
where SeqName = #SeqName )
begin
print 'Sequence already exists.'
return 1
end
if #seed is null set #seed = 1
if #incr is null set #incr = 1
set #currval = #seed
insert into AllSequences (SeqName, Seed, Incr, CurrVal)
values (#SeqName, #Seed, #Incr, #CurrVal)
end
go
create procedure usp_GetNewSeqVal
#SeqName nvarchar(255)
as
begin
declare #NewSeqVal int
set NOCOUNT ON
update AllSequences
set #NewSeqVal = CurrVal = CurrVal+Incr
where SeqName = #SeqName
if ##rowcount = 0 begin
print 'Sequence does not exist'
return
end
return #NewSeqVal
end
go