I can't seem to declare variables inside this procedure - mysql

I can't get this code to work, i keep getting syntax errors, and i don't see anything wrong with the declare sentences.
delimiter //
create procedure Plsql1 (Count int)
begin
CREATE TABLE alumnos(
nombre VARCHAR(7) primary key,
edad INT (7),
sexo INT (2));
DECLARE Count int default 10;
DECLARE Number int default 0;
DECLARE done int = 0;
etiq1: loop
if not done then
INSERT INTO alumnos VALUES(CONCAT('Victor',Number), Number*5, Number%2);
SET N=N+1;
if (Number=Count) SET done=1;
else
leave etiq1;
end if;
end loop;
SELECT * FROM alumnos;
end //
delimiter ;
When i try to get this to work, i get this:
ERROR 1064 (42000): 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 'DECLARE Count int default 10;
DECLARE Number int default 0;
DECL' at line 10
However, i can't see any syntax errors in there. Some advice for this, please?

You can create the table like that in the stored procedure:
CREATE PROCEDURE procedure1(IN tableName VARCHAR(255))
BEGIN
SET #sql = CONCAT('CREATE TABLE ', tableName, '(column1 INT(11))');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
// Do all other stuff then...
END
That should work.

Related

MYSQL error while executing SQL query stored in a column

I have two tables,
execution:
execution_id | order_id | execution_date
1 1 2014-03-16
2 1 2014-03-17
and queries:
query_name | code
CNT_EXEC | SELECT COUNT(execution_id) FROM `execution`
We have query defined in a column above. I am trying to execute this query using my code below;
DELIMITER //
DROP PROCEDURE IF EXISTS query_execute //
CREATE PROCEDURE query_execute()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE s_query varchar(255);
DECLARE c_queries CURSOR FOR
SELECT code FROM queries;/*since there are more than one queries in the actual query table*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN c_queries;
getquery: LOOP
FETCH c_queries INTO s_query;
IF finished = 1 THEN
LEAVE getquery;
END IF;
/*run the query*/
SET #sql = s_query;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
END //
DELIMITER ;
/*next I am trying to invoke the procedure and find the results*/
CREATE PROCEDURE queriesExecution()
BEGIN
SELECT query_name, query_execute() AS val
FROM queries;
END
Going by the MySQL documentation, it seems I am using the correct procedure to create the procedure.But here is the error I am getting;
ERROR 1064 (42000) in the pre-written template: 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 '' at line 5`.
As i already wrote in my comment, your approach doesn't work .
But you can change it a bit
First:
Change your queries, because you need a result
CREATE TABLE queries (
`query_name` VARCHAR(8),
`code` VARCHAR(355)
);
INSERT INTO queries
(`query_name`, `code`)
VALUES
('CNT_EXEC', 'SELECT COUNT(execution_id) INTO #result FROM `execution`');
As you can see the result is put into a user defined variable. so that ot can be used in the INSERT INT myresult
DELIMITER //
DROP PROCEDURE IF EXISTS query_execute //
CREATE PROCEDURE query_execute()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE s_query varchar(255);
DECLARE c_queries CURSOR FOR
SELECT code FROM queries;/*since there are more than one queries in the actual query table*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
CREATE TEMPORARY TABLe myresults(`query` varchar(255), result INT);
OPEN c_queries;
getquery: LOOP
FETCH c_queries INTO s_query;
IF finished = 1 THEN
LEAVE getquery;
END IF;
/*run the query*/
SET #sql = s_query;
PREPARE stmt FROM #sql;
EXECUTE stmt;
INSERT INTO myresults VALUES (s_query,#result);
DEALLOCATE PREPARE stmt;
END LOOP;
SELECT * FROM myresults;
DROP TEMPORARY TABLE myresults;
END //
DELIMITER ;
when you now call CALL query_execute();
you get
query result
SELECT COUNT(execution_id) INTO #result FROM `execution` 2
Of course as you add queries, you will get more rows.
this now assumes you get only INTEGER back in your queries, if not you must change the datatype.
This also only works, because your query returns only 1 result, if get more rows you can't use the user defined variables and you have to look for another approach.

MySQL: Prepare/Execute in procedure (concat)

i'm abit lost and i'm hoping for your help. I'm currently learning to work with Mysql and i got this procedure:
delimiter //
drop procedure price_update2 //
create procedure price_update2()
BEGIN
DECLARE n INT default 0;
DECLARE i INT default 1;
DECLARE cond varchar(255) default '';
SET cond = CONCAT('SELECT customer_id FROM customers LIMIT ',i,',1');
prepare stt FROM cond;
execute stt;
END //
for some reason i always get an error near the "cond; execute stt....". Probably it's just an easy thing, but i can't find it.
Also tried without concat:
delimiter //
drop procedure price_update2 //
create procedure price_update2()
BEGIN
DECLARE n INT default 0;
DECLARE i INT default 1;
DECLARE cond varchar(255) default '';
SET cond = 'SELECT customer_id FROM customers LIMIT 1';
prepare stt FROM cond;
execute stt;
END //
if i use the statement directly, it works fine.
This is an odd thing, but you need to use user-defined variables at this point:
delimiter //
drop procedure price_update2 //
create procedure price_update2()
BEGIN
DECLARE n INT default 0;
DECLARE i INT default 1;
SET #cond = CONCAT('SELECT customer_id FROM customers LIMIT ',i,',1');
prepare stt FROM #cond;
execute stt;
DEALLOCATE PREPARE stt; # don't forget to deallocate
END //
The manual states this:
A statement prepared in stored program context cannot refer to stored procedure or function parameters or local variables because they go out of scope when the program ends and would be unavailable were the statement to be executed later outside the program. As a workaround, refer instead to user-defined variables, which also have session scope

error in my procedure MySQL find value INT in all tables database

I want find a number of UserId from all tables call searchUser(3,'UserId')
error: 0 14:30:14 call searchUser(3,'UserId') Error Code: 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 'NULL' at line 1
DELIMITER $$
CREATE PROCEDURE `searchUser`( in_search int(11),in_column_name varchar(50) )
READS SQL DATA
BEGIN
DECLARE trunc_cmd VARCHAR(50);
DECLARE searchUserId int (11);
DECLARE db,tbl,clmn CHAR(50);
DECLARE done INT DEFAULT 0;
DECLARE COUNTER INT;
DECLARE table_cur CURSOR FOR
SELECT concat('SELECT COUNT(*) INTO #CNT_VALUE FROM `',table_name,'` WHERE `', in_column_name,'` = "',in_search,'"') ,table_name,column_name FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = 'comments' and column_name=in_column_name ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
PREPARE trunc_cmd FROM "TRUNCATE TABLE temp_details;";
EXECUTE trunc_cmd ;
OPEN table_cur;
table_loop:LOOP
FETCH table_cur INTO db, tbl, clmn;
SET #searchUserId = searchUserId;
SELECT searchUserId;
PREPARE searchUserId FROM #searchUserId;
EXECUTE searchUserId;
SET COUNTER = #CNT_VALUE;
SELECT COUNTER;
IF COUNTER>0 THEN
INSERT INTO temp_details VALUES(db,tbl,clmn);
END IF;
IF done=1 THEN
LEAVE table_loop;
END IF;
END LOOP;
CLOSE table_cur;
SELECT * FROM temp_details;
END
Problem must be due to:
DECLARE searchUserId int (11);
and:
SET #searchUserId = searchUserId;
SELECT searchUserId;
PREPARE searchUserId FROM #searchUserId;
EXECUTE searchUserId;
I assume that you are thinking searchUserId has a value. But nowhere in the code you assigned a value to it. By default it is a NULL. And hence the statement EXECUTE searchUserId is translate to EXECUTE NULL. This caused the error you specified.
To resolve it, you should first assign a proper value to the searchUserId variable declared.
BTW, why are you using the same variable name searchUserId for a local variable, global variable, and statement alias? It would confuse the readers of the program and hence is not advised to practice.
I guess problem lies in this statement-creation-statement:
SELECT concat('SELECT COUNT(*) INTO #CNT_VALUE FROM `',table_name,'` WHERE `', in_column_name,'` = "',in_search,'"') ,table_name,column_name FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = 'comments' and column_name=in_column_name ;
Please execute the statement standalone and see what you get.

Stored procedure error on CALL

I am trying to call a procedure which compiles successfully but on calling I get this error:
Query: call proc5
Error Code: 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 'NULL' at line 1
This is my Stored procedure:
DELIMITER $$
CREATE DEFINER = `root` #`localhost` PROCEDURE `proc5` ()
BEGIN
DECLARE done BOOL DEFAULT FALSE ;
DECLARE tablename VARCHAR (100) ;
DECLARE tracktables CURSOR FOR
SELECT
TABLE_NAME
FROM
information_schema.TABLES
WHERE TABLE_SCHEMA = 'db1' ;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE ;
OPEN tracktables ;
myloop :
LOOP
FETCH tracktables INTO tablename ;
IF done
THEN CLOSE tracktables ;
LEAVE myloop ;
END IF ;
SET #s = CONCAT(
'INSERT INTO db2.test1 SELECT * FROM ',
#tablename
) ;
PREPARE stmt1 FROM #s ;
EXECUTE stmt1 ;
DEALLOCATE PREPARE stmt1 ;
END LOOP ;
END $$
DELIMITER ;
Actually, I want to select all the tables from a database and insert those tables into one table which is in another database using MySQL Cursors. And when I call this stored procedure I get the above error.
The problem is that you are mixing declared variables and impromtu #vars.
var -> tablename does not equal var -> #tablename.
Change the set line to:
SET #s = CONCAT(
'INSERT INTO db2.test1 SELECT * FROM `'
,tablename
,'`'
) ;
Now it should work.
The backticks ` should not be needed, but are there just in case.

Error in stored procedure - column count does not match value

I've created a stored procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS `zero`.`sp_for_insert_into_account_db`$$
CREATE PROCEDURE `zero`.`sp_for_insert_into_account_db` (usr_key char(6),usr_name varchar(15),usr_password varchar(15),OUT output_message INT)
BEGIN
DECLARE no_of_row INT;
SELECT COUNT(*) INTO no_of_row from account_db;
IF no_of_row < 4 THEN
SET #s = CONCAT('insert into account_db (USR_KEY,USR_NAME,USR_PWD) VALUES (',usr_key,usr_name,usr_password,')');
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET output_message=1;
ELSE
SET output_message=0;
END IF;
END$$
DELIMITER ;
I'm calling it with query
call sp_for_insert_into_account_db('a','b','c',#output_ message);
The error is like:
Column count does not match value...
I'm passing 4 arguments...
Why is this error occurring?
I've already checked with this syntax (by default parameter is IN type)
sp_for_insert_into_account_db(IN usr_key char(6),
IN usr_name varchar(15),
IN usr_password varchar(15),
OUT output_message INT)
Problem is also here:
SET #s = CONCAT('insert into account_db (USR_KEY,USR_NAME,USR_PWD) VALUES (',usr_key,usr_name,usr_password,')');
You are trying to insert 3 values and the concatenation returns 1
use this instead:
SET #s = CONCAT('insert into account_db (USR_KEY,USR_NAME,USR_PWD) VALUES (\'',usr_key,'\',\'',usr_name,'\',\'',usr_password,'\')');
Not entirely sure why you're using prepared statements/dynamic sql when you dont need to ?? See the following example which i've cleaned up for you a little:
drop procedure if exists sp_for_insert_into_account_db;
delimiter #
create procedure sp_for_insert_into_account_db
(
in p_usr_key char(6),
in p_usr_name varchar(15),
in p_usr_pwd varchar(15),
out p_output_message tinyint unsigned
)
begin
declare v_no_of_row int unsigned default 0;
set p_output_message=0;
select count(*) into v_no_of_row from account_db;
if v_no_of_row < 4 then
insert into account_db(usr_key, usr_name, usr_pwd) values (p_usr_key, p_usr_name, p_usr_pwd);
set p_output_message = 1;
end if;
end#
delimiter ;
call sp_for_insert_into_account_db (...);
EDIT
are you a COBOL PROGRAMMER FROM THE 1970'S AND IS THAT WHY YOU HAVE TO USE CAPS ?