Does the MySQL prepare syntax not support the update statement? - mysql

I used the DBeaver to connect MySql.
CREATE TABLE `test2` (
`id` varchar(100) DEFAULT NULL,
`code` varchar(100) DEFAULT NULL,
`age` int DEFAULT NULL,
`name` varchar(100) DEFAULT NULL
);
INSERT INTO mp.test2
(id, code, age, name)
VALUES('abc', 'cc', 0, 'mike');
I create a temp script in DBeaver
and try to execute the sql script :
PREPARE stmt from 'update test2 set age = 3';
EXECUTE stmt ;
DEALLOCATE PREPARE stmt;
I get error: Unknown prepared statement handler (stmt) given to EXECUTE
I want to know what's wrong with this sql. what's the correct sql to update data by using Prepare?

Related

Create table and insert using variable

I'd like to create a table and insert data only changing the variable name.
but instead, it creates a table with the name #myId, and not with the value of the variable.
i also have tried to remove the `` but i got an sql error.
set #myId = "tabletest";
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
CREATE TABLE `#myId` (
`id` int(10) NOT NULL,
`position` int(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `#myId` (`id`, `position`) VALUES
(1, 1);
I am not recommending that you do this. Table names should not be coming from variables. However, you did ask a valid question and if you were going to do this, you need dynamic SQL:
SET #sql = 'CREATE TABLE #myId (id int(10) NOT NULL, position int(10) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1;';
SET #sql = REPLACE(#sql, '#myId', 'tabletest');
PREPARE ct FROM #sql;
EXECUTE ct;
DEALLOCATE PREPARE ct;
SET #sql = 'INSERT INTO #myId (id, position) VALUES (1, 1);';
SET #sql = REPLACE(#sql, '#myId', 'tabletest');
PREPARE st FROM #sql;
EXECUTE st;
DEALLOCATE PREPARE st;
You can then execute:
SELECT * FROM tabletest;
Note that if you wanted to use #myId in the SELECT, you would need more dynamic SQL: Yucch!
Usually the right solution is just a table where you insert rows with an identifier. You can then delete those rows (or invalidate them) if necessary when you are done.
Here is a db<>fiddle.

MySQL Stored Procedure running slow in PhpMyAdmin but fast in Workbench

I have created a stored procedure in MySQL which calls a view to fetch results.
I have executed the stored procedure in MySQL Workbench and its executing in 5 secs.
However, when I run the same in phpMyAdmin it takes 50 seconds.
I have researched and founded that collation of the table columns takes time for that i used the Convert() method on the column but didnt work.
Can anyone help?
Table Schema:
CREATE TABLE `inspection_transactions` (
`id` int NOT NULL,
`point_id` int DEFAULT NULL,
`inspection_id` int DEFAULT NULL,
`instruction_pool_id` int DEFAULT NULL,
`inspection_date` datetime DEFAULT NULL,
`user_id` int DEFAULT NULL,
`result` varchar(255) DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`comment2` varchar(255) DEFAULT NULL,
`inspection_company_transaction_id` int DEFAULT NULL,
`inspection_type` int DEFAULT NULL COMMENT '1:Single, 2:Company, 3:Home '
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
** View **
CREATE
ALGORITHM = UNDEFINED
DEFINER = `hms`#`localhost`
SQL SECURITY DEFINER
VIEW `testingdump`.`inspection_transactions_company_number_grouped_view` AS
SELECT
`inspection_transactions_company_number_view`.`point_id` AS `point_id`,
`inspection_transactions_company_number_view`.`point_name` AS `point_name`,
MONTH(`inspection_transactions_company_number_view`.`inspection_date`) AS `month`,
`inspection_transactions_company_number_view`.`inspection_date` AS `inspection_date`,
`inspection_transactions_company_number_view`.`inspection_id` AS `inspection_id`,
`inspection_transactions_company_number_view`.`instruction_pool_id` AS `instruction_pool_id`,
`inspection_transactions_company_number_view`.`inspection_company_transaction_id` AS `inspection_company_transaction_id`,
`inspection_transactions_company_number_view`.`customer_id` AS `customer_id`,
CONCAT(SUBSTR(`inspection_transactions_company_number_view`.`instruction_pool_name`,
1,
3),
' ',
SUM(`inspection_transactions_company_number_view`.`result`)) AS `result_concat`,
SUM(`inspection_transactions_company_number_view`.`result`) AS `result`,
`inspection_transactions_company_number_view`.`instruction_pool_name` AS `instruction_pool_name`
FROM
`testingdump`.`inspection_transactions_company_number_view`
GROUP BY `inspection_transactions_company_number_view`.`point_id` , `inspection_transactions_company_number_view`.`instruction_pool_id` , MONTH(`inspection_transactions_company_number_view`.`inspection_date`) , `inspection_transactions_company_number_view`.`inspection_company_transaction_id`
ORDER BY `inspection_transactions_company_number_view`.`point_id` , `inspection_transactions_company_number_view`.`instruction_pool_id` , MONTH(`inspection_transactions_company_number_view`.`inspection_date`);
** Stored Procedure **
DELIMITER $$
CREATE DEFINER=`hms`#`localhost` PROCEDURE `company_transactions_number_monthly_pivot`(IN cus_id INT, IN insp_id INT, IN start_date datetime, IN end_date datetime)
BEGIN
SET #sql = NULL;
DROP TABLE IF EXISTS tbl1;
CREATE TEMPORARY TABLE tbl1 AS
( SELECT point_id,point_name, instruction_pool_id, instruction_pool_name, month, convert(result using utf8) collate utf8_general_ci
FROM `inspection_transactions_company_number_grouped_view`
WHERE `customer_id` = cus_id AND `inspection_id` = insp_id and `inspection_date` > start_date and `inspection_date` < end_date
);
SET #sql = CONCAT('SELECT point_name, ', #sql, ' FROM tbl1 GROUP BY point_id');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;

How do I create table if a reference record doesn't exist else insert?

I designed a system which received request with ResortId, DayId, SkierId, Time, LiftId.
I created a table called day_resort with ResortId, DayId, and a reference which equals the concatenation of ResortId and DayId. When I received a request with Reference (ResortId + DayId) exists in the day_resort. I will simply find the table with name = Reference and insert SkierId, Time, and LiftId there. On the contrary, if I don't find certain Reference in day_resort, I will create a table name after ResortId + DayId, and I will insert the record with ResortId, DayId, ResortId + DayId into day_resort, after that, I will go to the table name after ResortId + DayId and insert a record with SkierId, Time, and LiftId.
Here is the example I tried:
DELIMITER //
DROP PROCEDURE IF EXISTS createLogTable;
CREATE PROCEDURE createLogTable(tblName VARCHAR(255))
BEGIN
SET #tableName = tblName;
SET #sql := CASE
WHEN NOT EXISTS (SELECT * FROM day_resort WHERE Reference = #tableName) THEN
'INSERT INTO day_resort (ResortId, DayId, Reference) VALUES ("Marriot", "21", "Marriot21")';
ELSE
CONCAT('INSERT INTO `' , #tableName, '` (SkierId, TIme, LiftId) VALUES ("111", "222", "333")');
END;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
CREATE TABLE IF NOT EXISTS #tableName (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
SkierId VARCHAR(255) NOT NULL
Time VARCHAR(255) NOT NULL,
LiftId VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
END //
I got an error of Error Code: 2014 Commands out of sync; you can't run this command now
Thanks for any help

Stored procedure for copying data

I am all new to creating procedures and triggers in MySQL, but have struggled with this over the last couple of days, and it simply will not work. The error messages, that I get from Mysql does not help me any longer.
So I am trying to create a procedure, which I need to run after an update. I will take any updates and store new data in a dynamic created table in another database.
Here it is:
CREATE PROCEDURE get_price_storage_table (IN market_id INT(11), OUT tablename VARCHAR(50))
BEGIN
SET #NUMBER = CEILING(market_id / 100000) * 100000;
SET tablename = CONCAT('price_',#NUMBER);
SET #SQL = CONCAT('CREATE TABLE IF NOT EXISTS data.',tablename,'(
`pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`fk_market_id` INT(11) UNSIGNED NOT NULL,
`fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
`price` DOUBLE NOT NULL,
`status` ENUM(\'enabled\',\'disabled\') NOT NULL,
`created` DATETIME NOT NULL,
PRIMARY KEY (`pk_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8')');
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
This need to be triggered after update, where the SQL goes like:
CREATE TRIGGER copy_price_data AFTER UPDATE ON price
FOR EACH ROW
BEGIN
IF NEW.updated <> OLD.updated THEN
SET #market_id = NEW.fk_market_id;
SET #tablename = NULL;
CALL create_price_storage_table(#market_id, #tablename);
SELECT #tablename;
SET #SQL = CONCAT(
'INSERT INTO ',
#tablename,
' (`fk_market_id`, `fk_outcome_type_id`, `price`, `status`, `created`) VALUES (NEW.fk_market_id, NEW.fk_outcome_type_id, NEW.price, NEW.status, NOW())');
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END;
When trying to create the procedure, then I get the following error message from MySQL:
CREATE PROCEDURE get_price_storage_table (IN market_id INT(11), OUT tablename VARCHAR(50))
BEGIN
SET #NUMBER = CEILING(market_id / 100000) * 100000;
MySQL returnerede: Dokumentation 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 '' at line 3
I hope someone with greater understanding than me, can point me in the right direction. Thanks.
Change:
CREATE PROCEDURE get_price_storage_table (IN market_id INT(11), OUT tablename VARCHAR(50))
BEGIN
SET #NUMBER = CEILING(market_id / 100000) * 100000;
SET tablename = CONCAT('price_',#NUMBER);
SET #SQL = CONCAT('CREATE TABLE IF NOT EXISTS data.',tablename,'(
`pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`fk_market_id` INT(11) UNSIGNED NOT NULL,
`fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
`price` DOUBLE NOT NULL,
`status` ENUM(\'enabled\',\'disabled\') NOT NULL,
`created` DATETIME NOT NULL,
PRIMARY KEY (`pk_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8')');
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
By:
CREATE PROCEDURE `get_price_storage_table`(`market_id` INT UNSIGNED, OUT `tablename` VARCHAR(50))
BEGIN
DECLARE `NUMBER` INT UNSIGNED;
SET `NUMBER` := CEILING(`market_id` / 100000) * 100000;
SET `tablename` := CONCAT('`price_', NUMBER, '`');
SET #`SQL` := CONCAT('CREATE TABLE IF NOT EXISTS ', tablename, '(
`pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`fk_market_id` INT(11) UNSIGNED NOT NULL,
`fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
`price` DOUBLE NOT NULL,
`status` ENUM(\'enabled\',\'disabled\') NOT NULL,
`created` DATETIME NOT NULL,
PRIMARY KEY (`pk_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8');
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8')');
PREPARE `stmt` FROM #`SQL`;
EXECUTE `stmt`;
DEALLOCATE PREPARE `stmt`;
END//
Example:
mysql> DROP PROCEDURE IF EXISTS `get_price_storage_table`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `get_price_storage_table`(`market_id` INT UNSIGNED, OUT `tablename` VARCHAR(50))
-> BEGIN
-> DECLARE `NUMBER` INT UNSIGNED;
-> SET `NUMBER` := CEILING(`market_id` / 100000) * 100000;
-> SET `tablename` := CONCAT('`price_', NUMBER, '`');
-> SET #`SQL` := CONCAT('CREATE TABLE IF NOT EXISTS ', tablename, '(
> `pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
> `fk_market_id` INT(11) UNSIGNED NOT NULL,
> `fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
> `price` DOUBLE NOT NULL,
> `status` ENUM(\'enabled\',\'disabled\') NOT NULL,
> `created` DATETIME NOT NULL,
> PRIMARY KEY (`pk_id`)
> ) ENGINE=InnoDB DEFAULT CHARSET=utf8');
-> PREPARE `stmt` FROM #`SQL`;
-> EXECUTE `stmt`;
-> DEALLOCATE PREPARE `stmt`;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `get_price_storage_table`(1, #`tablename`);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT #`tablename`;
+----------------+
| #`tablename` |
+----------------+
| `price_100000` |
+----------------+
1 row in set (0.00 sec)
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| price_100000 |
+----------------+
1 row in set (0.00 sec)
Syntax errors are to be located to the left (or above) of the place reported in the error message, since the reported place is the first thing that confuses MySQL.
In your case this is the ;
It finishes your CREATE PROCEDURE statement, but MySQL expects more to come, like an END.
Procedures / Triggers / Functions have to be declared with a different delimiter when they consist of more than one statement.
Try like this:
DELIMITER $$
CREATE PROCEDURE whatever()
BEGIN
SELECT 'whatever';
SELECT 'another';
END $$
DELIMITER ;

TRIGGER MYSQL NOT EXIST

I created this trigger:
CREATE TABLE `Invitations`
( `userId` varchar(255) NOT NULL, `name` varchar(255) DEFAULT NULL,
`status` varchar(1) DEFAULT NULL, `userId_inv` varchar(255) NOT NULL,
PRIMARY KEY (`userId`,`userId_inv`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TRIGGER `Invitation_001_after_trig` AFTER INSERT ON `invitation_001`
FOR EACH ROW
BEGIN
IF ((new.userId,'001') NOT EXISTS (SELECT `userId`,`userId_inv` FROM `Invitations`
WHERE `userId`= new.userId AND `userId_inv` = '001' LIMIT 1))
THEN
INSERT INTO `Invitations`(`userId`, `name`,`status`,`userId_inv`)
values (new.userId, new.name,new.status,'001');
DELETE FROM `invitation_001` WHERE `status` = 'a';
END IF;
END;
It did not work. I had this error:
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 'EXISTS (SELECT userId,userId_inv FROM Invitations WHERE
userId= new.user' at line 1
So could you help me.
I resolved the problem with this trigger:
CREATE TRIGGER `Invitation_001_after_trig` AFTER INSERT ON `invitation_001`
FOR EACH ROW
BEGIN
INSERT INTO `Invitations` (`userId`, `name` ,`status` ,`userId_inv`) SELECT * FROM
invitation_001 iv WHERE
NOT EXISTS (SELECT 1 FROM `Invitations` ivs WHERE ivs.`userId` = iv.`userId` AND
ivs.`userId_inv` = iv.`userId_inv`) AND iv.`userId_inv`='001';END;
Now I've an other issue. I would like to execute a query from a Concat String in a trigger but until now I did not succeed so here is my code:
CREATE TRIGGER `InvitationS_after_trig` AFTER INSERT ON `Invitations`
FOR EACH ROW
BEGIN
if(new.status ='c' OR new.status ='r')
BEGIN
SET #query = CONCAT("INSERT INTO", Invetations.userId,"values(new.userId,new.name,new.status,new.userId_inv);");
PREPARE stmt1 FROM #query;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END IF;
END;
I resolved the syntax problem but I now have an other one:
Dynamic SQL is not allowed in stored function or trigger
I'm using MySQL version 5.1.69.
Finally I give up, I will resolve this problem using java Fonction