I was wondering if you can tell me what's wrong with the ff sql statement:
insert into translog
select * from transponder_logs where trans_log_id < 150000;
delete from transponder_logs where trans_log_id < 150000
This statement ran just fine in sql but it gives me a syntax error when I used it on event scheduler.
The error message was:
"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 'delete from transponder_logs where trans_log_id < 150000 at line 3"
Whenever you define code like routines that have multiple executable statements, you MUST define a custom DELIMITER. And your code will be sent to the server along with delimiter instruction. And the server compiles the code as a block before it finds the newly defined custom delimiter.
Read what documentation says:
Defining Stored Programs
If you use the mysql client program to define a stored program containing semicolon characters, a problem arises. By default, mysql itself recognizes the semicolon as a statement delimiter, so you must redefine the delimiter temporarily to cause mysql to pass the entire stored program definition to the server.
To redefine the mysql delimiter, use the delimiter command. .... The delimiter is changed to // to enable the entire definition to be passed to the server as a single statement, and then restored to ; before invoking the procedure. This enables the ; delimiter used in the procedure body to be passed through to the server rather than being interpreted by mysql itself.
I believe your event scheduler code is just executed as is without defining such delimiter.
Change it as following:
-- set the new delimiter
DELIMITER //
-- include your event scheduler code block here
-- lastly terminate the code block, with new delimiter
-- so that server starts compiling the code
//
-- now reset the delimiter to default
DELIMITER ;
Refer to: CREATE EVENT Syntax
Related
So I have this SQL file whose contents are like below
DELIMITER $$
CREATE PROCEDURE FOO(....)
BEGIN
Insert into BAR(...) Values(....);
Insert into BARTOO(...) Values(...);
END$$
DELIMITER ;
Now this seems to work just fine when we I use the mysql client to execute this script. However If i pass it to initialize as a --init-file=./myscript.sql this fails with the follow error
2020-06-04T04:22:37.307204Z 5 [ERROR] [MY-000061] [Server] 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 'DELIMITER
$$ CREATE PROCEDURE FOO(..... at line 1.
Initially this made sense that the keyword DELIMITER is not supported by the SQL syntax and that this is purely a client related command.Does that mean you cannot create a multi-line stored procedure using an --init-file? is there another way to create this procedure on initialization?
I also came across this bug report (https://bugs.mysql.com/bug.php?id=17843) that seems to indicate that DELMITER is supported in --init-file??
very confused, please help.
I don't known about mysql but there's an open bug on mariadb : https://jira.mariadb.org/browse/MDEV-18394
The dev team seems to say that this is the same behavior as mysql. They are probably not going to fix this soon as this is marked as a feature request.
I don't know about the context in which you are using this init script, but in my case this is for a container initialization, which makes it hard to use the mysql client. I ended up using a small shell script as my entry point, starting the mysqld in the background with a minimal init file, waiting a little bit, then passing the commands with the mysql client, then putting the mysqld back to foreground.
Single-line procedures do appear to work in init files:
init.sql
USE mysql;
CREATE OR REPLACE DEFINER='root'#'localhost' PROCEDURE abc() READS SQL DATA BEGIN SELECT 1; SELECT 2; SELECT 3; END;
I need to create a trigger in sql server via R code for which I need to set my sql delimiter to //.
I tried doing the following:
dbExecute(con, "delimiter //")
dbExecute(con, "delimiter //\n")
dbExecute(con, "delimiter //\t")
I also tried the above scenarios with other DBI functions like
dbGetQuery and dbSendQuery
but I am getting the following error.
could not run statement: 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 'delimiter //' at line 1
It turns out that in order to execute an sql trigger through R using the DBI package, one does not need to set and unset the delimiter. We can directly execute the trigger command.
This is unlike what needs to be done while setting a triggers through SQL command line where, since the trigger syntax itself includes a semicolon ;, in order to avoid conflict with the default SQL delimiter which is also ; we temporarily set the delimiter to a lesser used special character such as // with a command such as
delimiter //
and then revert back to the default delimiter with
delimiter ;
which need not be done when trigger is executed through DBI package of R.
In my model I defined some procedures. The code (generated by MySQL Workbench) contains DELIMITER definitions, so the procedures look like:
-- schema
CREATE DATABASE ...
CREATE TABLE foo ...
-- procedures
DELIMITER $$
...
BEGIN
DECLARE ... ;
OPEN ... ;
SET ... ;
... ;
END$$
DELIMITER ;
Now I need to "import" the SQL to the database via PDO. I tried to pass it as input for the PDO#exec(...), but noticed, that the execution stops on the line of the first DELIMITER definition.
I don't want remove the DELIMITER statements. So the the SQL code should remain the same.
How to use PDO to execute SQL code containing DELIMITER statements?
From comments:
I don't want remove the DELIMITER statements. And actually I want to get it working without to execute every statement manually
That's not how it works.
To understand why, you need to understand how the mysql CLI -- and any other program that can read and execute a dump file like this -- actually handles it.
DELIMITER is not something the server understands.
DELIMITER is used to tell the client-side parser what the current statement delimiter should be, so that the client-side parser can correctly split the statements and deliver one at a time to the server for execution.
From the docs. Note carefully that mysql, every time it is used here, refers to the mysql client utility -- not the server.
If you use the mysql client program to define a stored program containing semicolon characters, a problem arises. By default, mysql itself recognizes the semicolon as a statement delimiter, so you must redefine the delimiter temporarily to cause mysql to pass the entire stored program definition to the server.
To redefine the mysql delimiter, use the delimiter command. [...] The delimiter is changed to // to enable the entire definition to be passed to the server as a single statement, and then restored to ; before invoking the procedure. This enables the ; delimiter used in the procedure body to be passed through to the server rather than being interpreted by mysql itself.
https://dev.mysql.com/doc/refman/5.7/en/stored-programs-defining.html
So, to handle such a file, you need a client-side parser that does the same thing mysql does... and here, the code you are writing is (needs to be) the client-side statement parser. So you are the one that needs to write the logic to handle the delimiter.
To do what you want, you have to interpret the DELIMITER statements, use them to keep track of the current statement delimiter, but do not send them to the server.
Then, you have to read through the input one line at a time, buffering what you've read, until you find the specified delimiter at the end of the line, and send the resulting statement to the server -- excluding the actual statement delimiter from what you send... so, for example, you would not send the ending $$ after the procedure body (unless the current statement delimiter is ;, which you can either send or not send -- the server doesn't care.) Then empty the buffer and start reading again until you see another instance of a delimiter (and send the statement to the server) or match a DELIMITER statement and set your code's current delimiter variable to match it so that you correctly identify the end of the next statement.
Delimiters is a thing that you don't need with PDO. You can just run your queries as is
$pdo->query("CREATE DATABASE ...");
$pdo->query("CREATE TABLE foo ...");
$pdo->query("BEGIN
DECLARE ... ;
OPEN ... ;
SET ... ;
... ;
END");
as simple as that
I met same problem with you when I tried with PostgreSQL. The problem seems PDO just allow you execute 1 query 1 time. As mentioned: PDO::exec() executes an SQL statement in a single function call, returning the number of rows affected by the statement. In php manual
Could you try this:
$stmt = $db->prepare($sql);
$stmt->execute();
Or with mysqli: multi_query. php manual
Here my whole class: http://sandbox.onlinephpfunctions.com/code/f0528fda6d7bd097c3199f1f3c019805a163ae3a
i wat to create this trigger to set a defaul value for a clomn but i get this message error : #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 4
this is my script :
CREATE TRIGGER trg_set_content_val BEFORE INSERT
ON post_table
FOR EACH ROW BEGIN
set NEW.content = 'mu value here';
END;
You need to set the delimiter to something else than semicolon before the stored program and then change it back:
DELIMITER //
CREATE TRIGGER trg_set_content_val
BEFORE INSERT
ON post_table
FOR EACH ROW BEGIN
set NEW.content = 'mu value here';
END//
DELIMITER ;
Reason:
If you use the mysql client program to define a stored program
containing semicolon characters, a problem arises. By default, mysql
itself recognizes the semicolon as a statement delimiter, so you must
redefine the delimiter temporarily to cause mysql to pass the entire
stored program definition to the server.
To redefine the mysql delimiter, use the delimiter command. The
following example shows how to do this for the dorepeat() procedure
just shown. The delimiter is changed to // to enable the entire
definition to be passed to the server as a single statement, and then
restored to ; before invoking the procedure. This enables the ;
delimiter used in the procedure body to be passed through to the
server rather than being interpreted by mysql itself.
So I have this stored proc that will not get created when I run the file.
DELIMITER //
DROP PROCEDURE IF EXISTS msd.test_proc//
CREATE PROCEDURE msd.test_proc()
BEGIN
SELECT
'Hello proc'
FROM
msd.zipcode_lookup;
END//
DELIMITER ;
When I run this I get an error code 1064 at line 1 when I execute in RazorSQL. Here is the complete error message:
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 '//
CREATE PROCEDURE msd.test_proc()
BEGIN
SELECT
'Hello proc'
FROM ' at line 1
Error Code:1064
I've tried other variations and still get errors. I am sure this is something basic I am missing. I appreciate any help.
Thanks.
As stated on the RazorSQL website:
The DELIMITER statement is not part of the MySQL language. It is a command supported by certain MySQL tools. This command tells those MySQL programs to scan for a certain character that indicates the end of a query or statement.
RazorSQL does not support using the DELIMITER command. The SQL statement delimiter value used by RazorSQL can be changed using the preferences window. The default values is the semi-colon.