MySQL, MyBatis, Grammar error - mysql

I have an application using MyBatis, and I'm trying to add a select SQL that has multiple statements.
<select id="getReleaseDetails" resultType="maingrid" statementType="STATEMENT">
DROP TEMPORARY TABLE IF EXISTS vrTmp;
DROP TEMPORARY TABLE IF EXISTS vrTmp2;
CREATE TEMPORARY TABLE vrTmp AS (
SELECT vr.*, v.Code
...etc.
However, I keep getting the error:
Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'DROP TEMPORARY TABLE IF EXISTS vrTmp2;
CREATE TEMPORARY TABLE vrTmp AS (
S' at line 2
]
2014-03-11 12:48:20,069 [bio-8080-exec-3] DEBUG DataSourceUtils - Returning JDBC Connection to DataSource
2014-03-11 12:48:20,085 [bio-8080-exec-3] ERROR VRMService - Error in getDetails :
### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'DROP TEMPORARY TABLE IF EXISTS vrTmp2;
CREATE TEMPORARY TABLE vrTmp AS (
S' at line 2
The error may exist in mappings/mapping.xml
The SQL works fine in SQLYog, using the same database login.
What am I missing? It's almost like it does not like the ";" to separate the individual statements.
Thanks

Figured it out: by default the MySQL connection does not allow execution of multiple SQLs. It has to be specified in the URL:
url="jdbc:mysql://ln-ct-dv-my1:3306/TestDB?allowMultiQueries=true"
... and I had to remove the "StatementType" from the mapping file.

Here are some problems.
You can not use multiple statements in single tag in mybatis. Hence you can not use ";"
If at all if you want to use create table statement use insert tag.
The solution would be to use stored procedure to run multiple statements.
Here is an example for stored procedure and how to call it from mybatis.
CREATE OR REPLACE PROCEDURE KP_PRC AS
BEGIN
execute immediate 'DROP TEMPORARY TABLE IF EXISTS vrTmp';
execute immediate 'DROP TEMPORARY TABLE IF EXISTS vrTmp2';
execute immediate 'CREATE TEMPORARY TABLE vrTmp AS (SELECT vr.*, v.Code';
commit;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END KP_PRC;
Mybatis xml.
<select id="kpSpCall" statementType="CALLABLE">
{CALL KP_PRC()}
</select>

Related

My SQL Syntax error for multiple commands in one query, working for each command running separately

I'm trying to run the following MySQL command:
USE database_name;
DROP TEMPORARY TABLE IF EXISTS only_with_balance;
DROP TEMPORARY TABLE IF EXISTS keys_to_match;
CREATE TEMPORARY TABLE only_with_balance as (
SELECT
*
FROM
transactions t
WHERE
t.balance is not NULL
and (t.transaction_status_id = 4 or t.transaction_status_id = 5)
and (t.date between "2022-05-01" and "2022-08-24" )
);
But I'm getting a syntax error while trying to run the all the commands at once.
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 'DROP TEMPORARY TABLE IF EXISTS only_with_balance;
DROP TEMPORARY TABLE IF EXIST' at line 2
When I run each command separately, the result is the expected.
Can someone help me here?
What am I forgetting?
In MySQL, by default the query interface only allows one SQL statement per call.
There's an option to enable multi-query per call, but it must be set at connect time. Some MySQL connectors do this by default, or allow it as an option, but some do not. You didn't say if you're writing code or if you're submitting this set of queries through a client (though you tag the question 'dbeaver' you don't say anything else about that). So I can't guess what interface you're using for these queries.
Anyway, there's no advantage to using multi-query. The default mode is one SQL statement per call. That's what I do.
Using the default mode of a single SQL statement per call has some advantages:
Supports prepared statements and bound parameters (you can't run multiple statements in a single prepare call, even if you enable multi-query).
Simplifies processing errors and warnings.
Simplifies processing result sets.

ERROR 1146 (42S02): Table 'mysql.proc' doesn't exist while calling a stored procedure

I am using this thread -
Rename a mysql procedure
to rename a stored procedure
Here upon trying the command as shown in the answer -
UPDATE `mysql`.`proc`
SET name = '<new_proc_name>',
specific_name = '<new_proc_name>'
WHERE db = '<database>' AND
name = '<old_proc_name>';
I get the error -
ERROR 1146 (42S02): Table 'mysql.proc' doesn't exist while calling a stored procedure
Here regarding the other questions regarding mysql.proc does not exit, none address the specific problem of calling a stored procedure.
The mysql.proc table was removed in MySQL 8.0. See No more mysql.proc in MySQL 8.0
You can use information_schema.routines to get information about stored procedures. But this is a read-only view, you can't update it. So I don't think there's any simple way to rename procedures any more. You may be able to use dynamic SQL to define the procedure with the new name using this information.
EDIT:
Unfortunately, the above is not possible just in MySQL, because CREATE PROCEDURE can't be executed using PREPARE, and information_schema.routines doesn't contain all the information needed to recreate the procedure. You could do it in an external language by performing a SHOW CREATE PROCEDURE query and then replacing the name to form a new query.
Recommend avoid fiddling with any mysql table directly.
Use show create procedure old_proc_name
And then create procedure new_proc_name ....
And drop the old drop procedure old_proc_name

Creating stored procedure on MySQL

I'm trying to run the query below, that is stored in a .sql file, then read with ioutils.ReadFile and executed on initialization
CREATE TABLE IF NOT EXISTS districts
(
GeoCode integer PRIMARY KEY,
name varchar(32)
);
drop procedure if exists insert_district;
DELIMITER $$
CREATE PROCEDURE insert_district(in pgeocode int, in pname varchar(32))
BEGIN
INSERT INTO districts(geocode, name) VALUES (pgeocode, pname);
SELECT * FROM districts where geocode = pgeocode;
END$$
DELIMITER ;
I am using the database/sql package and run the query with Exec
Error 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 'drop procedure if exists insert_district;
DELIMITER $$
CREATE PROCEDURE insert' at line 7
To the best of my knowledge my syntax is correct, and I tested it so I cannot figure out why the same exact query cannot be run properly from the program.
The Go MySQL client does not support multiple SQL statements by default. You can't just feed it a text file with ; separated statements.
See Does a Go Mysql driver exist that supports multiple statements within a single string? for details — there's an option you can use to allow multi-statements.
But that still won't support statements like DELIMITER which are not recognized by the MySQL Server. That's a mysql client command.
You have two alternatives:
Parse the .sql file to find statement terminators and run the statements one at a time.
Execute the mysql client in a sub-process using the .sql file as input.

MySQL Truncate Table Before Insert

I am creating a table in MySQL for which I only ever want it to contain one tuple at a time. To enforce this, I am trying to create a trigger which will truncate the table each time an INSERT occurs. However, I am running into problems.
SQL:
CREATE TRIGGER `tbl_hire_truncate`
BEFORE INSERT ON `tbl_hire`
FOR EACH ROW
BEGIN
TRUNCATE TABLE `tbl_hire`;
END
Error:
#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 5
Every example of a trigger that I've seen uses a FOR EACH loop, but it certainly doesn't make much sense with what I am trying to achieve.
How can I rewrite my SQL to achieve my goal?

How can I drop a table whose name is "logs/#sql-ib203" that appeared after a MySQL crash?

DROP TABLE logs/#sql-ib203 does not work due to /:
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 '/#sql-ib203' at line 1
The table logs/#sql-ib203 appeared after a database crash (not enough disk space while re-indexing and deleting some attributes in a table in the logs database). SHOW TABLES does not list the table logs/#sql-ib203, but when trying to ALTER the table that was being changed during the crash MySQL complains about the existence of the table logs/#sql-ib203:
ERROR 1050: Table 'logs/#sql-ib203' already exists
SQL Statement:
ALTER TABLE logs.srv_logs DROP COLUMN filenum , DROP COLUMN
agent , DROP COLUMN ip , DROP COLUMN event_source
I use MySQL 5.6.12-winx64 and InnoDB.
Try to execute:
DROP TABLE `logs/#sql-ib203`
Need to wrap the name with ``, that should drop it.
Regards.
You can do a dump of your database, the orphaned innodb temporary table is not referred in the dump file, then you can drop the database and restore again.
Also you can try ; drop table #mysql50##sql-ib203;
Reference : http://dev.mysql.com/doc/refman/5.6/en/identifier-mapping.html