Temporary Table in Stored Procedure Not Found in MySQL - mysql

I've inherited some code that uses stored procedures and one of them doesn't appear to be working correctly.
The stored procedure uses a temporary table to insert data later in the procedure. However when I execute the stored procedure, no data is inserted. When I debug it, I get the error:
Table 'db.testtable' doesn't exist
I've stripped down the stored procedure to the following code, and it doesn't work. I always get the error on the SELECT statement. Everything looks OK from what I can tell based on the examples I've seen.
DROP PROCEDURE IF EXISTS db.insert_record;
CREATE PROCEDURE db.`insert_record`(id int, status int)
BEGIN
DECLARE code varchar(45);
DROP TEMPORARY TABLE IF EXISTS testTable;
CREATE TEMPORARY TABLE testTable AS (SELECT 'TEST' AS fakeColumn);
SELECT fakeColumn INTO code FROM testTable;
END;
I've also verified that the user I am connected as has the permission to create temporary tables; in fact it has every permission available
Additional Details
Running MySQL 5.6 on Windows.
If I take the drop / create / select statements by themselves and run as a script, it behaves as expected.
Using Toad for MySQL to debug the stored procedure.

I can't reproduce the problem. What other information can you provide?
mysql> USE `test`;
Database changed
mysql> SELECT VERSION();
+-----------------+
| VERSION() |
+-----------------+
| 5.5.22-0ubuntu1 |
+-----------------+
1 row in set (0.00 sec)
mysql> DELIMITER //
mysql> DROP PROCEDURE IF EXISTS `insert_record`//
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE PROCEDURE `insert_record`(`id` int, `status` int)
-> BEGIN
-> DECLARE `code` VARCHAR(45);
-> DROP TEMPORARY TABLE IF EXISTS `testTable`;
-> CREATE TEMPORARY TABLE `testTable` AS (SELECT 'TEST' AS `fakeColumn`);
-> SELECT `fakeColumn` INTO `code` FROM `testTable`;
-> SELECT `code`;
-> END//
Query OK, 0 rows affected (0.01 sec)
mysql> CALL `insert_record`(NULL, NULL)//
+--------+
| `code` |
+--------+
| TEST |
+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
SQL Fiddle demo

Related

MySql update. difference between procedure results and phpmyadmin sql

I am having difficult getting a procedure to update a table in the way I require. I am using phpmyadmin on my local computer. In phpmyadmin I can put the following code into the SQL tab and one row will be updated:
SET `adjCost` = 22.05 WHERE `Name` LIKE CONCAT('magic', '%') AND `idKey` = '2016fulham02345';
As expected and wanted, IF the name begins with magic AND the idKey is '2016fulham02345' THEN the adjCost is updated to 22.05.
There will be between 2 and 50 rows with the same idKey. The Name will never be repeated in a set with the same idKey.
I created a procedure with the following parameters:
IN idK VARCHAR 255 Charset
IN aName VARCHAR 255 Charset
IN cost FLOAT 5,2
BEGIN
UPDATE `raceresults` SET `adjCost` = cost WHERE `Name` LIKE CONCAT(aName, '%') AND `idKey` = idK;
END
When I run this procedure it updates ALL adjCost where the idKey = idk and (seems) to ignore the name parameter.
I have tried concatenating the name string first:
BEGIN
SELECT CONCAT(aName, '%') INTO #str;
UPDATE `raceresults` SET `adjCost` = cost WHERE `Name` = #str AND `idKey` = idK;
END
but to no avail.
I looked through w3schools, stackoverflow and google and have not been able to find the answer.
My question is:
How can I correct my procedure to get it to work as I would like?
UPDATE: as requested.
CREATE DEFINER=`root`#`localhost` PROCEDURE `importAltUpdateAjdCost`(IN `idK` VARCHAR(255), IN `aName` VARCHAR(255), IN `cost` FLOAT(5,2))
NO SQL
BEGIN
UPDATE `costingPP`
SET `adjCost` = cost
WHERE
`Name` LIKE CONCAT(aName, '%')
AND
`idKey` = idK;
END
To get this, I selected export on my list of procedures on phpmyadmin.
I'm not entirely sure what or how you did, but here's what I did and it instantly worked. Since you didn't specify MySQL version, I used 5.7.
EDIT: Now as I went back to see your procedure creation statement I realised that NO SQL was introduced in MySQL 8.0. Since your procedure clearly is SQL then please remove the NO SQL and re-create the procedure.
I'm leaving my MySQL 5.7 sample here for reference:
1) Created a simple table:
mysql> CREATE TABLE raceresults (
-> idKey VARCHAR(255),
-> Name VARCHAR(255),
-> adjCost FLOAT(5,2)
-> );
Query OK, 0 rows affected (0.06 sec)
2) Here we insert a sample data row:
mysql> INSERT INTO raceresults VALUES ('2016fulham02345', 'magicFlyingHorse', 0.00);
Query OK, 1 row affected (0.01 sec)
3) To create a (STORED) PROCEDURE we have to temporarily set a different delimiter, so query parser wouldn't terminate procedure creation on default semi-colon, as it's used inside the procedure. After delimiter's change we create the procedure and set the delimiter back to semi-colon
mysql> DELIMITER //
mysql> CREATE PROCEDURE update_test(IN idK VARCHAR(255), IN aName VARCHAR(255), IN cost FLOAT(5,2))
-> BEGIN
-> UPDATE `raceresults` SET `adjCost` = cost WHERE `Name` LIKE CONCAT(aName, '%') AND `idKey` = idK;
-> END//
mysql> DELIMITER ;
Query OK, 0 rows affected (0.00 sec)
4) Now let's see how it all works. Before and after the procedure call I'm selecting the rows from database. You can see the cost column value changing:
mysql> SELECT * FROM raceresults;
+-----------------+------------------+---------+
| idKey | Name | adjCost |
+-----------------+------------------+---------+
| 2016fulham02345 | magicFlyingHorse | 0.00 |
+-----------------+------------------+---------+
1 row in set (0.00 sec)
mysql> CALL update_test('2016fulham02345', 'magic', 1.23);
Query OK, 1 row affected (0.02 sec)
mysql> SELECT * FROM raceresults;
+-----------------+------------------+---------+
| idKey | Name | adjCost |
+-----------------+------------------+---------+
| 2016fulham02345 | magicFlyingHorse | 1.23 |
+-----------------+------------------+---------+
1 row in set (0.00 sec)
And now one piece of advise too:
If possible, use only lower case table, column, indexes, functions, procedures, etc... names, while always writing all SQL commands in uppercase (which you did). This is kind of a de facto standard and makes life easier both for you and others reading your code.

MySQL Stored procedure with local variable not working in LINUX

I'm struggling with a simple stored procedure, that I've reduced to this:
CREATE PROCEDURE RemoveDuplicateModules()
BEGIN
SET #myvar=1;
End;
When I run this in the MySQL CLI I get: parameter #myvar has not been created. I'm struggling cause in windows it works fine!
mysql --version = 5.6.33
Works for me (debian, mysql 5.6.25):
mysql> delimiter //
mysql> CREATE PROCEDURE RemoveDuplicateModules()
-> BEGIN
-> SET #myvar=1;
-> End;
-> //
Query OK, 0 rows affected (0,66 sec)
mysql> call RemoveDuplicateModules();
Query OK, 0 rows affected (0,00 sec)
mysql> select #myvar ;
+--------+
| #myvar |
+--------+
| 1 |
+--------+
1 row in set (0,02 sec)
Seems that the problem here was not that the procedure I posted was failing, but since it was being executed in a larger context, a big file with a lot of code from a lot of people, a previous lack of a commit made my procedure to fail. Anyway, thanks for the help!

Can't create table throught a view with function inside mysql

I created two tables
CREATE TABLE `prova` (
`id` int NOT NULL AUTO_INCREMENT ,
`text` varchar(255) NOT NULL ,
PRIMARY KEY (`id`)
)
;
CREATE TABLE `prova2` (
`id2` int NOT NULL AUTO_INCREMENT ,
`text2` varchar(255) NOT NULL ,
PRIMARY KEY (`id2`)
)
;
insert into prova (text) values ('ffffff');
A function does a select on table one and inserts a row in table two only if the value of variable #test is set to 0:
CREATE FUNCTION `get_prova`()
RETURNS int(11)
BEGIN
declare id_prova int ;
declare test int ;
set #test = 1;
set #id_prova = (select id from prova limit 1);
if (#test = 0) THEN
insert into prova2 (text2) values ('dddd');
end if;
return #id_prova;
END;
then, I create a view that calls this function:
create view temp_prova as
select id,
text,
get_prova() as prova
from prova
I want to create table 3 that contains the result of view:
CREATE TABLE zzz_prova SELECT * FROM temp_prova;
but when I try to create table zzz_prova I get this error:
[SQL]CREATE TABLE zzz_prova SELECT * FROM temp_prova; [Err] 1746 -
Can't update table 'prova2' while 'zzz_prova' is being created.
Why does this error show up?
Thank you
What version of MySQL are you running?
Changes in MySQL 5.6.2 (2011-04-11)
Incompatible Change; Replication: It is no longer possible to issue a
CREATE TABLE ... SELECT statement which changes any tables other than
the table being created. Any such statement is not executed and
instead fails with an error.
One consequence of this change is that FOR UPDATE may no longer be
used at all with the SELECT portion of a CREATE TABLE ... SELECT.
This means that, prior to upgrading from a previous release, you
should rewrite any CREATE TABLE ... SELECT statements that cause
changes in other tables so that the statements no longer do so.
This change also has implications for statement-based replication
between a MySQL 5.6 (or later slave) and a master running a previous
version of MySQL. In such a case, if a CREATE TABLE ... SELECT
statement on the master that causes changes in other tables succeeds
on the master, the statement nonetheless fails on the slave, causing
replication to stop. To keep this from happening, you should either
use row-based replication, or rewrite the offending statement before
running it on the master. (Bug #11749792, Bug #11745361, Bug #39804,
Bug #55876)
References: See also Bug #47899.
UPDATE
MySQL 5.5:
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.5.47 |
+-----------+
1 row in set (0.00 sec)
mysql> DROP FUNCTION IF EXISTS `f`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `t1`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `t2`;
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER |
mysql> CREATE FUNCTION `f`()
-> RETURNS INT
-> BEGIN
-> INSERT INTO `t2` VALUES (1);
-> RETURN 1;
-> END|
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CREATE TABLE `t2`(`c1` INT);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `t1` SELECT `f`() `c1`;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT `c1` FROM `t1`;
+------+
| c1 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> SELECT `c1` FROM `t2`;
+------+
| c1 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
MySQL 5.6:
mysql> SELECT VERSION();
+-----------------+
| VERSION() |
+-----------------+
| 5.6.25 |
+-----------------+
1 row in set (0.00 sec)
mysql> DROP FUNCTION IF EXISTS `f`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DROP TABLE IF EXISTS `t1`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DROP TABLE IF EXISTS `t2`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DELIMITER |
mysql> CREATE FUNCTION `f`()
-> RETURNS INT
-> BEGIN
-> INSERT INTO `t2` VALUES (1);
-> RETURN 1;
-> END|
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CREATE TABLE `t2`(`c1` INT);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `t1` SELECT `f`() `c1`;
ERROR 1746 (HY000): Can't update table 't2' while 't1' is being created.

why i can not create event in mysql

I am trying to create event for one of my database using below code,
use testing;
show events;
show warnings;
set global event_scheduler =on;
DELIMITER $$
create event table_backup_testingTo_test on schedule every 1 day
starts '2015-10-14 16:40:00'
do
select * into test.event_table_testing from testing.manitest;
DELIMITER $$
After run this code if i check in show events then there is no event in the name of table_backup_testingTo_test
where am i doing mistake?
Note : I am using mysql workbench 6.3
You change the delimiter, but actually never finish a statement with it. And after the multiple statements you should change the delimiter back to default. In your case you don't need a delimiter at all, since it's just one statement. Try like this:
DELIMITER ; /*assuming it's still set to $$*/
use testing;
show events;
show warnings;
set global event_scheduler =on;
create event table_backup_testingTo_test on schedule every 1 day
starts '2015-10-14 16:40:00'
do
select * into test.event_table_testing from testing.manitest;
Or, if you have multiple statements in your event:
use testing;
show events;
show warnings;
set global event_scheduler =on;
DELIMITER $$
create event table_backup_testingTo_test on schedule every 1 day
starts '2015-10-14 16:40:00'
do
begin
select * into test.event_table_testing from testing.manitest;
select 'we have multiple statements here';
end $$
DELIMITER ;
My test:
mysql> CREATE DATABASE `testing`;
Query OK, 1 row affected (0.00 sec)
mysql> USE `testing`;
Database changed
mysql> CREATE TABLE `manitest` (
-> `column_0` int,
-> `column_1` varchar(7),
-> `column_2` varchar(55)
-> );
mysql> INSERT INTO `manitest`
-> (`column_0`, `column_1`, `column_2`)
-> VALUES
-> (1, 'value_1_0', 'value_2_0'),
-> (2, 'value_1_1', 'value_2_1'),
-> (3, 'value_1_2', 'value_2_2');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> CREATE DATABASE `test`;
Query OK, 1 row affected (0.00 sec)
mysql> USE `test`;
Database changed
mysql> CREATE TABLE `event_table_testing` (
-> `column_0` int,
-> `column_1` varchar(7),
-> `column_2` varchar(55)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * INTO `test`.`event_table_testing`
-> FROM `testing`.`manitest`;
ERROR 1327 (42000): Undeclared variable: test
mysql> INSERT INTO `test`.`event_table_testing`
-> SELECT * FROM `testing`.`manitest`;
Query OK, 3 rows affected (0.00 sec)
mysql> CREATE EVENT `table_backup_testingTo_test` ON SCHEDULE EVERY 1 DAY
-> STARTS '2015-10-14 16:40:00'
-> DO
-> -- select * into test.event_table_testing from testing.manitest;
-> INSERT INTO `test`.`event_table_testing`
-> SELECT * FROM `testing`.`manitest`;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW EVENTS\G
*************************** 1. row ***************************
Db: test
Name: table_backup_testingTo_test
.
.
.
1 row in set (0.00 sec)

how to create procedures in mysql

I am creating procedure in mysql. but I am facing some issues while creating that.
I am applying query i.e
CREATE PROCEDURE simpleproc( param1 INT) BEGIN SELECT COUNT(*)
INTO param1 FROM 91_nidhi; END//
and The error is
#1064 - You have an error in your SQL syntax; c
heck the manual that corresponds to your MySQL server version for the
right syntax to use near '' at line 1
This how you need to do
- You are not passing any input value rather you are using an output value
- so specify the param as OUT
Below is the example
mysql> create table 91_nidhi (id int,val varchar(20));
Query OK, 0 rows affected (0.09 sec)
mysql> insert into 91_nidhi values (1,'aa'),(2,'bb'),(3,'cc');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
Now lets create the procedure
delimiter //
CREATE PROCEDURE simpleproc( out param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM 91_nidhi;
END; //
Then change the delimiter in the terminal as
mysql> delimiter ;
Now lets call the procedure
mysql> call simpleproc(#res);
Query OK, 0 rows affected (0.00 sec)
mysql> select #res ;
+------+
| #res |
+------+
| 3 |
+------+
1 row in set (0.00 sec)