Mysql stored function freezing - mysql

I have a stored function in MySQL and it works partially.
DELIMITER $$
DROP FUNCTION IF EXISTS `getsubdomain`$$
CREATE FUNCTION getsubdomain(page_id int(11))
RETURNS CHAR(255)
DETERMINISTIC
READS SQL DATA
SQL SECURITY INVOKER
BEGIN
declare current_p_id int(11);
declare current_p_parent_id int(11);
declare current_p_address_type char(255);
declare current_p_adress char(255);
SET current_p_id = page_id;
WHILE (current_p_id) <> 0
DO
select p_parent_id, p_address_type, p_adress from opu_pages where p_id = current_p_id into current_p_parent_id, current_p_address_type, current_p_adress;
IF current_p_address_type <> ''
THEN
IF current_p_address_type = 'subdomain'
THEN
RETURN current_p_adress;
ELSE
SET current_p_id = current_p_parent_id;
END IF;
ELSE
RETURN NULL;
END IF;
END WHILE;
RETURN NULL;
END$$
DELIMITER ;
If I call in query SELECT getsubdomain(p_id) FROM opu_pages; it works Ok. But if I call it in SELECT * FROM opu_pages WHERE getsubdomain(p_id)='library'; the database is collapsed and freezing.
Query and function work with one table.
What did I do wrong?
I thought that it can be caused by the table format MyISAM. But I can't change it to InnoDB because I use FULLTEXTFORMAT fields in this table.
Table opu_pages (MyISAM) scheme
p_id INT
p_parent_id INT
p_address_type ENUM (path, subdomain)
p_adress VARCHAR

Based on your post I would say that your code is entering an infinite loop for some of your input parameters.
In particular the case where p_id = p_parent_id in the opu_pages table and the current_p_address_type = 'subdomain'

Related

Mysql Trigger null result

SET SQL_SAFE_UPDATES = 0;
use my_database;
DELIMITER $$
DROP PROCEDURE IF EXISTS Comit $$
CREATE PROCEDURE Comit ()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE ids INT;
DECLARE leftChilds INT;
DECLARE cur CURSOR FOR SELECT id FROM user;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
ins_loop: LOOP
FETCH cur INTO ids;
IF done THEN
LEAVE ins_loop;
END IF;
SET leftChilds = ( SELECT turnoverBalance FROM user WHERE proposer = ids AND side = 'left' LIMIT 1 );
INSERT INTO log(`log`) VALUES ( leftChilds );
END LOOP;
CLOSE cur;
END $$
When i call the procedure call Comit(); that return me this error :
1048 - Column 'log' cannot be null
Your subquery is generating NULL values, probably because there is no match on the proposer condition. Of course, your data could also have NULL values for turnoverBalance in user or rows with no 'left' side.
In any case, why are you using a cursor for something that is easily done as a single query? Something like this can replace all the logic:
INSERT INTO log(log)
SELECT turoverBalance
FROM user
WHERE proposer IN (SELECT id FROM user) AND side = 'left')
GROUP BY proposer;
First, its are stored procedure, not a trigger.
Check what your set leftChilds query returns, it should return some value, run it individually.
You can Check in stored procedure
If(leftChilds not NULL)
insert into log('log') values (leftChilds)

MySQL 5.6 Declare Issue

Let's see if I can edit this and put the whole procedure in.
I am trying to convert an Oracle database to MySQL. I have all the tables, keys, indexes, and views converted. I now need to convert a stored procedure to MySQL.
I have most of it done, and there is only one hang up on my code:
set dns1_tmp = X.X.X.X;
SET dns2_tmp = X.X.X.X;
This gives me an error of 1064 Syntax Error: Missing semicolon
I have tested the rest of my procedure, and it works fine. It creates it, runs it, and retrieves data from it, but only if I remove those two lines.
Any ideas on what I can do?
Whole stored procedure:
DELIMITER //
USE `TEST`//
DROP PROCEDURE IF EXISTS `proc_IN`//
CREATE DEFINER=`root`#`localhost` PROCEDURE `proc_IN`
(IN DNIS VARCHAR(20),
IN MSISDN VARCHAR(20),
IN AVPAIR1 VARCHAR(20),
IN AVPAIR2 VARCHAR(20),
IN GROUPID VARCHAR(20),
OUT DNS1 VARCHAR(15),
OUT DNS2 VARCHAR(15),
OUT AUTHSTAT VARCHAR(100))
BEGIN
declare dns1_tmp varchar(15);
declare dns2_tmp varchar(15);
set dns1_tmp = X.X.X.X;
SET dns2_tmp = X.X.X.X;
DECLARE avpair1_tmp varchar(15);
DECLARE avpair2_tmp varchar(15);
DECLARE grpid_tmp varchar(15);
DECLARE C_USER CURSOR FOR SELECT AVPAIR1, AVPAIR2, DNS1, DNS2, GROUPID FROM GRP, ALLMEMBER WHERE ALLMEMBER.GROUPID=GRP.GROUPID
UNION
SELECT AVPAIR1, AVPAIR2, DNS1, DNS2, GROUPID FROM GRP;
OPEN C_USER;
FETCH C_USER INTO AVPAIR1, AVPAIR2, DNS1, DNS2, GROUPID;
LOOP
FETCH C_USER INTO avpair1_tmp, avpair2_tmp, dns1_tmp, dns2_tmp, grpid_tmp;
INSERT INTO duplog VALUES(DNIS, MSISDN, avpair1_tmp, avpair2_tmp, dns1_tmp,dns2_tmp, grpid_tmp, SYSDATE);
END LOOP;
IF C_USER%ROWCOUNT > 1 THEN
INSERT INTO duplog VALUES(DNIS, MSISDN, AVPAIR1, AVPAIR2, DNS1,DNS2, GROUPID, SYSDATE);
SET AUTHSTAT := 'ok';
elseif C_USER%ROWCOUNT = 1 THEN
SET AUTHSTAT := 'ok';
ELSE
SET AUTHSTAT := NULL;
END IF;
CLOSE C_USER;
COMMIT;
END //
DELIMITER ;

MySQL query - weird syntax error

I'm using phpmyadmin and MySQL to run a simple query, that creates a function checking the existence of a certain record. It keeps throwing a syntax error at line 7 with Declare. I have no idea why. I did try to use the built-in function creator, but it's messed up and I don't like it. Any help appreciated!
CREATE FUNCTION check_if_card_exists (_name TEXT)
RETURNS INT
DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE res INT; --line 7
IF EXISTS (SELECT `name` FROM `cards` WHERE `name` = _name)
THEN SET res = 1;
ELSE SET res = 0;
END IF;
RETURN res;
END
Try the following:
DELIMITER $$
DROP FUNCTION IF EXISTS `check_if_card_exists`$$
CREATE FUNCTION check_if_card_exists (_name TEXT)
RETURNS INT
DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE res INT; --line 7
IF EXISTS (SELECT `name` FROM `cards` WHERE `name` = _name)
THEN SET res = 1;
ELSE SET res = 0;
END IF;
RETURN res;
END$$
DELIMITER ;

Dynamic SQL query within a procedure

I want to create a table dynamical but my built string to create the table is NULL - why?
The goal is to get column values from an existing table and create a new table with columns named with these values.
DELIMITER $$
DROP PROCEDURE IF EXISTS fanart_test.get_incomplete_artwork $$
CREATE PROCEDURE fanart_test.get_incomplete_artwork()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE type_id INT;
DECLARE type_name INT;
DECLARE build_string VARCHAR(20000);
DECLARE cursor1 CURSOR FOR
SELECT type_id,type_name FROM fanart_types WHERE type_section = 3;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN cursor1;
get_results: LOOP
FETCH cursor1 INTO type_id, type_name;
IF finished = 1
THEN LEAVE get_results;
END IF;
IF build_string = ""
THEN SET build_string = CONCAT('CREATE TABLE `tmp_incomplete_artwork`(`', type_name, '` TEXT');
ELSE SET build_string = CONCAT(build_string,',', type_name);
END IF;
SET build_string = CONCAT(build_string,')');
END LOOP get_results;
CLOSE cursor1;
SET #s = build_string;
PREPARE build FROM #s;
EXECUTE build;
DEALLOCATE PREPARE build;
END $$
DECLARE build_string VARCHAR(20000);
The build_string is not set to anything initially, so it'll probably be NULL.
IF build_string = ""
This will never return true, since NULL = "" is not true.
ELSE SET build_string = CONCAT(build_string,',', type_name);
Concatenating any string with NULL returns NULL.
Re your comment:
You have named your variables type_id and type_name which are the same as your column names in your table. This creates an ambiguity, and it turns out that MySQL prefers to interpret the identifiers as the local variables, instead of column names.
So this:
SELECT type_id,type_name FROM fanart_types WHERE type_section = 3;
Will return the current value of type_id and type_name, which is uninitialized, i.e. NULL. Therefore a pair of NULLs are returned for all rows of the table.
Just rename the variables to be distinct from your table's column names, or else qualify the columns so they are clearly columns instead of variables:
SELECT f.type_id, f.type_name FROM fanart_types f WHERE f.type_section = 3;
Also you probably want to declare type_name as TEXT instead of INT.

MYSQL function, is it Workbench or just noobish me?

I have been sitting with a stored procedure for MySQL for days now, it just won't work, so I thought I'd go back to basic and do a very simple function that checks if an item exists or not.
The problem I had on the first one was that it said END IF is invalid syntax on one of my IF clauses, but not the other two. The second one won't even recognize BEGIN as valid syntax...
Is it I that got everything wrong, or have I stumbled upon a MYSQL Workbench bug? I have Workbench 5.2 (latest version when I'm writing this) and this is the code:
DELIMITER $$
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT)
BEGIN
DECLARE check_val INT;
DECLARE return_val INT;
SELECT stockId
FROM orders
WHERE stockId = movie_id
INTO check_val;
IF check_val <= 0
THEN
SET return_val = 1;
ELSE
SET return_val = 0;
END IF;
RETURN return_val;
END
to fix the "begin" syntax error, you have to declare a return value, like this:
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT) RETURNS INT(11)
after doing that, Workbench won't return an error anymore ;o)
You have to specify the return value in signature as well delimiter at the end is missing. So, your function should look like
DELIMITER $$
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT) RETURNS INT
BEGIN
DECLARE check_val INT;
DECLARE return_val INT;
SELECT stockId
FROM orders
WHERE stockId = movie_id
INTO check_val;
IF check_val <= 0
THEN
SET return_val = 1;
ELSE
SET return_val = 0;
END IF;
RETURN return_val;
END
$$
DELIMITER $$
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT)
BEGIN
DECLARE check_val INT;
DECLARE return_val INT;
SELECT stockId
FROM orders
WHERE stockId = movie_id
INTO check_val;
IF check_val <= 0
THEN
SET return_val = 1;
ELSE
SET return_val = 0;
END IF;
RETURN return_val;
END
$$
DELIMITER ;
Add this last thing it works :
$$
DELIMITER ;
it means you are using ( ; ) this in function so for that reason we use it..see
and see also
MySQL - Trouble with creating user defined function (UDF)