I am looking for help with my sql procedure.
I would like to substring in loop each username, and alias from two input arguments and add it into table users. I have two procedures.
Sorry for Polish variable names and procedure names.
My first procedure is
CREATE DEFINER=`root`#`localhost` PROCEDURE `dodajZawodnika`(IN `dane` VARCHAR(50), IN `wyswietlanie` VARCHAR(50))
NO SQL
BEGIN
IF (SELECT 1 = 1 from zawodnicy where danezawodnika = dane AND dowyswietlenia=wyswietlanie) THEN
BEGIN
Select id from zawodnicy where danezawodnika=dane AND dowyswietlenia=wyswietlanie;
END;
ELSE
BEGIN
Insert INTO zawodnicy (danezawodnika, dowyswietlenia) VALUES(dane, wyswietlanie);
SELECT last_insert_id() AS ID;
END;
END IF;
END;
My second procedure is
CREATE DEFINER=`root`#`localhost` PROCEDURE `stworzSklad`(IN `dane` VARCHAR(1500), IN `pseudo` VARCHAR(1000))
NO SQL
BEGIN
DECLARE counter INTEGER;
DECLARE zawodnik VARCHAR(1500);
DECLARE pseudonim VARCHAR(1000);
DECLARE zawodnicy VARCHAR(1500);
DECLARE pseudonimy VARCHAR(1000);
DECLARE exit handler for sqlexception
BEGIN
-- ERROR
ROLLBACK;
END;
DECLARE exit handler for sqlwarning
BEGIN
-- WARNING
ROLLBACK;
END;
set counter = 0;
set #zawodnicy = dane;
set #pseudonimy = psuedo;
select #zawodnicy, #pseudonimy;
REPEAT
set zawodnik=(SELECT TRIM(SUBSTRING_INDEX(#zawodnicy, ',', 1)));
set pseudonim=(SELECT TRIM(SUBSTRING_INDEX(#pseudonimy, ',', 1)));
call dodajZawodnika(zawodnik, pseudonim);
SELECT RIGHT(#zawodnicy, TRIM(length(#zawodnicy) - length(SUBSTRING_INDEX(#zawodnicy, ',', 1)) - 1)) into #zawodnicy;
SELECT RIGHT(#pseudonimy, TRIM(length(#pseudonimy) - length(SUBSTRING_INDEX(#pseudonimy, ',', 1)) - 1)) into #pseudonimy;
select zawodnik as 'zawodnik', pseudonim as 'pseudonim', dane as 'dane', pseudo as 'pseudo', #zawodnicy as 'zawodnicy', #pseudonimy as 'pseudonimy';
set counter = counter + 1;
UNTIL (#zawodnicy = '' or counter = 30)
END REPEAT;
select counter;
END
I am fighting with it from about 2 hours.
I would like to use also transaction for this insert.
Please help me with this little problem.
How to make this in proper way?
Now, calling stworzSklad procedure make endless loop (ofc without counter in until condition) and any of user was not inserted in my table.
Cheers!
Related
I'm trying to create a IF statement with mySQL...
This is the if in Oracle SQL
CREATE OR REPLACE TRIGGER pruef
BEFORE INSERT ON belegung
FOR EACH ROW
DECLARE
counter_1 INTEGER;
beleg INTEGER;
max_platz INTEGER;
BEGIN
SELECT :new.kurs_id into beleg from dual;
SELECT COUNT (*) INTO counter_1 FROM belegung WHERE kurs_id = beleg;
SELECT max_personen INTO max_platz FROM KURS WHERE kurs_id = beleg;
IF counter_1 >= max_platz THEN
RAISE_APPLICATION_ERROR(-20101, 'Maximale Teilnehmerzahl überschritten');
END IF;
END;
/
And this is the mySQL Code
delimiter //
CREATE TRIGGER pruef_mysql
BEFORE INSERT ON BELEGUNG
FOR EACH ROW BEGIN
BEGIN
DECLARE 'counter_1' INT;
'beleg' INT;
'max_platz' INT;
SELECT new.kurs_id into 'beleg' FROM dual;
SELECT (*) INTO 'counter_1' FROM 'belegung' WHERE kurs_id=beleg;
SELECT 'max_personen' INTO 'max_platz' FROM 'KURS' WHERE kurs_id = beleg;
IF ('counter_1' >= 'max_platz', signal sqlstate -20101 set msgtext= 'Maximale Teilnehmerzahl überschritten');
END IF;
END//
DELIMITER ;
I don't know how I do this... Maybe searched on the wrong pages.
IF function and IF statement are two different things in MySQL
You want to use the later one
https://dev.mysql.com/doc/refman/8.0/en/if.html
I have spent quite a long time to figure out.. so my update statement is affecting 0 rows although I know for a fact that it should affect at least affect more than a few rows as I have tried as a standalone. In place of update statement I tried select statement and it is working so does that mean that update statement is not supposed to work in stored procedure.. I kinda doubt it.. so I would like to get a second opinion.
my stored procedure code here:
DELIMITER $$
CREATE PROCEDURE updateKeywordsInRIConsole(in retailerId int )
BEGIN
declare key_words varchar(200) default null;
declare grpid bigint(20);
declare finished bool default false;
declare cur1 cursor for
select Keywords, GRPID
from RIConsole
where RetailerID = retailerId
and DateCreated > date(now()) - interval 1 year
and INSTR(Keywords, "offer_page") = false;
declare continue handler for not found set finished = 1;
declare exit handler for sqlexception
begin
show errors;
end;
declare exit handler for sqlwarning
begin
show warnings;
end;
open cur1;
start_loop: loop
fetch cur1 into key_words, grpid;
if finished = 1 then
leave start_loop;
end if;
update RIConsole set Keywords = concat(key_words, " ",
"offer_page") where GRPID = cast(grpid as signed); <-- this code not working...I called it with cast function to make sure.. and i also tried without it.
end loop start_loop;
close cur1;
END $$
DELIMITER ;
DROP PROCEDURE updateKeywordsInRIConsole;
Yes, you can do an UPDATE in a stored procedure.
If you are happy with your SELECT, you could do the while thing in a single statement. e.g.
CREATE PROCEDURE updateKeywordsInRIConsole(IN retailerId INT)
BEGIN
UPDATE RIConsole
SET Keywords = CONCAT(Keywords, " ", "offer_page")
WHERE where RetailerID = retailerId
AND DateCreated > DATE(NOW()) - INTERVAL 1 YEAR
AND INSTR(Keywords, "offer_page") = false;
END
;
Why would my SQL throw an error like LEAVE with no matching label: tableList
DELIMITER $$
DROP PROCEDURE IF EXISTS CountSignatures$$
CREATE PROCEDURE CountSignatures()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE signatureCount INT;
DECLARE tableName CHAR(100);
DECLARE tableList CURSOR FOR Select table_name from information_schema.tables where table_schema="LogData" and table_name like "%FAULT_20150320%";
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN tableList;
tableListLoop: LOOP
SET done = FALSE ;
FETCH tableList INTO tableName;
IF done THEN
LEAVE tableListLoop;
END IF;
***select signatureCount := signatureCount + count(distinct signature) from tableList;*** Line giving syntax error
END LOOP;
CLOSE tableList;
END$$
DELIMITER;
leave lable:
This statement is used to exit the flow control construct that has the
given label. If the label is for the outermost stored program block,
LEAVE exits the program.
In your code tableList is a cursor, you should leaved the tableListLoop not tableList, so try:
LEAVE tableListLoop;
I'm not sure why it would generate that particular error, but this line is not correct:
signatureCount = signatureCount + Select count (distinct signature) from tableList;
If you want to update the variable, try:
set signatureCount = (signatureCount +
(select count(distinct signature)
from tableList));
However, you don't initialize the variable, so this will just produce NULL anyway.
I have a little problem. Looks like the procedure does not exist. Somehow it's dropped after the creation. I get different error each time i change something. I'm not really sure what's causing the error, maybe I'm not allowed to drop procedures and creating them in the same query.
I hope you guys can help me out.
drop procedure if exists refIntChk;
DELIMITER //
CREATE PROCEDURE refIntChk(IN district INT(11), OUT b INT(1))
BEGIN
DECLARE b INT(1);
IF district IN (select dist FROM t13)
THEN
SET b = 1;
ELSE
SET b = 0;
END IF;
END; //
DELIMITER ;
drop procedure gen if exists ;
DELIMITER //
CREATE PROCEDURE gen()
BEGIN
DECLARE rows INT(11) DEFAULT (SELECT COUNT(dist) FROM t13);
DECLARE district INT(11);
DECLARE custname VARCHAR(16);
DECLARE revenue FLOAT;
DECLARE x INT DEFAULT 10000;
DECLARE outvar INT(11);
WHILE x > 0
DO
SET district = FLOOR(RAND()*rows)+1;
CALL refIntChk(district, outvar);
IF outvar = 1
THEN
SET custname = substring(MD5(RAND()), -16);
SET revenue = (RAND() * 10);
INSERT INTO t14 VALUES(NULL, custname, district, revenue);
SET x = x - 1;
END IF;
END WHILE;
END;//
DELIMITER ;
CALL gen();
When you get errors, it's usually good to run each statement, one by one, and see which one is producing the error.
The second DROP procedure statement should be:
drop procedure if exists gen;
I am learning stored procedures, cursors in mysql and I stumble on it:
delimiter //
CREATE PROCEDURE some_func()
BEGIN
DECLARE link_rewrite VARCHAR(255);
DECLARE link_rewrite_cursor CURSOR FOR SELECT link_rewrite FROM prod;
OPEN link_rewrite_cursor;
SET #count = 0;
WHILE #count < 10 DO
FETCH link_rewrite_cursor INTO link_rewrite;
SELECT link_rewrite;
set #count = #count + 1;
END WHILE;
CLOSE link_rewrite_cursor;
END//
delimiter ;
My question is: Why SELECT link_rewrite always returns NULL (in prod table there is 9000 rows). SELECT link_rewrite FROM prod returns a lot of rows(9000 rows).
You should avoid using the same name for multiple different things. Specifically, give the variable a different name than the column you are selecting. For example, if you rename the variable v_link_rewrite then it will probably work:
delimiter //
DROP PROCEDURE IF EXISTS some_func //
CREATE PROCEDURE some_func()
BEGIN
DECLARE v_link_rewrite VARCHAR(255);
DECLARE link_rewrite_cursor CURSOR FOR SELECT link_rewrite FROM prod;
OPEN link_rewrite_cursor;
SET #count = 0;
WHILE #count < 10 DO
FETCH link_rewrite_cursor INTO v_link_rewrite;
SELECT v_link_rewrite;
set #count = #count + 1;
END WHILE;
CLOSE link_rewrite_cursor;
END//
delimiter ;
If you just want to select the top 10 rows, do this:
select link_rewrite from prod limit 10
It's much quicker and you don't have to go with a cursor.