Bug #46429 use DELIMITER command in MySql.Data.MySqlClient.MySqlScript
| Submitted: | 28 Jul 2009 14:09 | Modified: | 17 Feb 2010 15:32 |
|---|---|---|---|
| Reporter: | Laurent Yin | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | Connector / NET | Severity: | S3 (Non-critical) |
| Version: | trunk | OS: | Windows |
| Assigned to: | Reggie Burnett | CPU Architecture: | Any |
| Tags: | DELIMITER, mysqlscript | ||
[28 Jul 2009 14:10]
Laurent Yin
a dump file that doesn't work while trying to execute script
Attachment: dump.sql (application/octet-stream, text), 2.91 KiB.
[28 Jul 2009 14:21]
Valeriy Kravchuk
DELIMITER is not a server's statement, it is client command of mysql command line client. Check http://dev.mysql.com/doc/refman/5.1/en/stored-programs-defining.html and http://dev.mysql.com/doc/refman/5.1/en/mysql-commands.html for the details. Looks like you will have to parse the file, but it should be easy to do...
[28 Jul 2009 14:58]
Laurent Yin
it shouldn't be that easy, I have to find lines in the form DELIMITER $something$, while trying to find out if it is a command that is supposed to be processed or just part of a quoted string containing a newline. I was hoping I could take advantage of the parsing that you probably already do in the library. Is there any other way I can use the connector to execute a .sql file? I wanted to issue a "source" command, but it doesn't work if the file is not on the server.
[29 Jul 2009 1:43]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/79499 698 Reggie Burnett 2009-07-28 - fixed MySqlScript class so that it respects delimiter statements (bug #46429)
[29 Jul 2009 1:44]
Reggie Burnett
fixed in 5.2.8 and later. Starting with 5.2.8 and 6.0.5 and 6.1.1 our MySqlScript class now supports the delimiter statement as it is found in sql scripts.
[29 Jul 2009 8:29]
Laurent Yin
Thanks Reggie. This is much appreciated. I was struggling with the fact that it could be part of a string, or that the delimiter could be enclosed with single-quotes, double-quotes or nothing at all. Your way looks much simpler. I'll get the connector once it is released.
[4 Aug 2009 9:58]
Tony Bedford
An entry has been added to the 5.2.8, 6.0.5 and 6.1.1 changelogs:
When trying to create stored procedures from a SQL script, a MySqlException was thrown when attempting to redefine the DELIMITER:
MySql.Data.MySqlClient.MySqlException was unhandled
Message="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"
Source="MySql.Data"
ErrorCode=-2147467259
Number=1064
StackTrace:
à MySql.Data.MySqlClient.MySqlStream.ReadPacket()
à MySql.Data.MySqlClient.NativeDriver.ReadResult(UInt64& affectedRows, Int64&
lastInsertId)
à MySql.Data.MySqlClient.MySqlDataReader.GetResultSet()
à MySql.Data.MySqlClient.MySqlDataReader.NextResult()
à MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
à MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
à MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
à MySql.Data.MySqlClient.MySqlScript.Execute()
Note: The MySqlScript class has been fixed to support the delimiter statement as it is found in SQL scripts.
[3 Nov 2009 21:56]
Werner Wolf
Sorry, does not work on my platform. Connector c# 6.1.2 VS2005, .NET 2.0 SP1, C# DROP PROCEDURE IF EXISTS "GetConsultantInfo"; DELIMITER $$ CREATE PROCEDURE "GetConsultantInfo"(OUT pResult VARCHAR(500)) BEGIN select 'abc' into pResult; END $$ DELIMITER ;
[4 Nov 2009 23:33]
MySQL Verification Team
See bug: http://bugs.mysql.com/bug.php?id=48548.
[6 Nov 2009 19:34]
Tonci Grgin
Not repeatable with latest sources from trunk:
using (MySqlConnection cn = new MySqlConnection("DataSource=xx;Database=test;UserID=xx;Password=xx;PORT=xx;logging=True;charset=utf8;"))
{
cn.Open();
MySqlScript script = new MySqlScript(cn, File.ReadAllText(@"bug46429.sql"));
try
{
script.Execute();
}
catch (Exception ex)
{
Console.Out.WriteLine(DateTime.UtcNow.ToLongTimeString() + " " + "Exception: " + ex.Message);
throw;
}
}
Script bug46429.sql:
DROP PROCEDURE IF EXISTS `bug46429`;
DELIMITER $$
CREATE PROCEDURE `bug46429`(OUT pResult VARCHAR(500))
BEGIN
select 'abc' into pResult;
END $$
DELIMITER ;
Output:
WindowsFormsApplication1.vshost.exe Information: 0 : [06.11.09 20:29:56] -
====== Query logged ======
Time of query: 06.11.09 20:29:56
host: xx
time of execution: 0.0004623 seconds (0.4623 milliseconds
-- Result --
Rows affected: 0
Inserted Id (if any): 0
Command text:
DROP PROCEDURE IF EXISTS `bug46429`
====== End of Query ======
WindowsFormsApplication1.vshost.exe Information: 0 : [06.11.09 20:29:56] -
====== Query logged ======
Time of query: 06.11.09 20:29:56
host: xx
time of execution: 0.0007034 seconds (0.7034 milliseconds
-- Result --
Rows affected: 0
Inserted Id (if any): 0
Command text:
CREATE PROCEDURE `bug46429`(OUT pResult VARCHAR(500))
BEGIN
select 'abc' into pResult;
END
====== End of Query ======
[23 Nov 2009 8:56]
Tonci Grgin
The problem is fixed in source trees, versions 5.2.8, 6.0.5 and 6.1.3.
[25 Nov 2009 14:14]
Sergei Shirokov
Problem still exists in 6.1.3.0. Please take a look to the attached project, which 100% reproduces the problem. The bug in the 'BreakIntoStatements' method, exactly in the "startPos = endPos + delimiter.Length;" line. There should be 'currentDelimiter' (instead of 'delimiter' which is actually member field).
[25 Nov 2009 14:15]
Sergei Shirokov
Test VS2008 project to reproduce the problem on 6.1.3 version
Attachment: TryDelimiter.zip (application/zip, text), 123.54 KiB.
[25 Nov 2009 14:21]
Tonci Grgin
Sergei, will retest soon.
[27 Nov 2009 8:27]
Tonci Grgin
Sergei's test case (attached) fails against every tree in source repository. Problem seems to be in parsing second SP:
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 'ySuperDelimiter
CREATE PROCEDURE TestProcedure2()
BEGIN
SELECT * FROM mysql' at line 1
However, this is partially related to protocol:
mysql> DELIMITER MySuperDelimiter
mysql>
mysql> CREATE PROCEDURE TestProcedure1()
-> BEGIN
-> SELECT * FROM mysql.proc;
-> END MySuperDelimiter
Query OK, 0 rows affected (0.00 sec)
->
-> CREATE PROCEDURE TestProcedure2()
-> BEGIN
-> SELECT * FROM mysql.proc;
-> END MySuperDelimiter
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 'r
CREATE PROCEDURE TestProcedure2()
BEGIN
SELECT * FROM mysql.proc;
END' at line 1
->
-> DELIMITER ;
-> \c
mysql>
Protocol depends on the length of actual delimiter used:
mysql> DELIMITER MyDelimiter
mysql>
mysql> CREATE PROCEDURE TestProcedure1()
-> BEGIN
-> SELECT * FROM mysql.proc;
-> END MyDelimiter
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> CREATE PROCEDURE TestProcedure2()
-> BEGIN
-> SELECT * FROM mysql.proc;
-> END MyDelimiter
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> DELIMITER ;
Shortening the delimiter to "MyDelimiter" or even "MyDeli" in Sergei's test, doesn't help c/NET though so we do have a bug here:
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 'yDeli(miter)
CREATE PROCEDURE TestProcedure2()
BEGIN
SELECT * FROM mysql.proc' at line 1
The bug in c/NET is that it can't deal with *two* consecutive CREATE PROCEDURE statements using custom delimiter. This is *not* the original bug reported! Original bug is fixed.
Bug in server docs is in that it does not describe maximum length for custom delimiter (or I can not find it).
As a workaround, I suggest to execute SP creation DML's one by one.
[15 Jan 2010 7:30]
Tonci Grgin
Assigning Reggie and rising Priority to get full fix for this.
[15 Feb 2010 21:27]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/100448 793 Reggie Burnett 2010-02-15 - fixed issue with script execution & multi-char delimiters (bug #46429)
[15 Feb 2010 21:27]
Reggie Burnett
Fixed in 6.0.6, 6.1.4, 6.2.3, and 6.3.1+
[17 Feb 2010 15:32]
Tony Bedford
Changelog entry updated.
[21 Jul 2015 15:38]
Jimmy Bosse
This bug seems to have regressed in version 6.9.7.0 of the ADO.Net driver for MySQL
[22 Mar 2016 19:35]
Kai Neumann
On 6.9.8, too.
I have the problem on Win 7x64, VS2013 C#, Server 5.6.29
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
DELIMITER $$\r\n
USE `elite_db`$$
CREATE DEFINER = CURRENT_USER TRIGGER `elite_db`.`tbCommodityData_AFTER_INSERT` AFTER INSERT ON `tbCommodityData` FOR EACH ROW
BEGIN
INSERT INTO `elite_db`.`tbPriceHistory`
(`station_id`, `commodity_id`, `Sell`, `Buy`, `Demand`, `DemandLevel`, `Supply`, `SupplyLevel`, `Sources_id`, `timestamp`)
VALUES
(NEW.`station_id`, NEW.`commodity_id`, NEW.`Sell`, NEW.`Buy`, NEW.`Demand`, NEW.`DemandLevel`, NEW.`Supply`, NEW.`SupplyLevel`, NEW.`Sources_id`, NEW.`timestamp`);
END$$
USE `elite_db`$$
CREATE DEFINER = CURRENT_USER TRIGGER `elite_db`.`tbCommodityData_AFTER_UPDATE` AFTER UPDATE ON `tbCommodityData` FOR EACH ROW
BEGIN
IF (NEW.Sell <> OLD.Sell) OR (NEW.Buy <> OLD.Buy) OR (NEW.Sources_id <> OLD.Sources_id) OR
(TIMESTAMPDIFF(hour, OLD.timestamp, NEW.timestamp) > 24) THEN
INSERT INTO `elite_db`.`tbPriceHistory`
(`station_id`, `commodity_id`, `Sell`, `Buy`, `Demand`, `DemandLevel`, `Supply`, `SupplyLevel`, `Sources_id`, `timestamp`)
VALUES
(NEW.`station_id`, NEW.`commodity_id`, NEW.`Sell`, NEW.`Buy`, NEW.`Demand`, NEW.`DemandLevel`, NEW.`Supply`, NEW.`SupplyLevel`, NEW.`Sources_id`, NEW.`timestamp`);
END IF;
END$$
DELIMITER ;\r\n
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.053 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: I dumped a database and I would like to restore it programmatically using .Net connector. Restoring tables works perfectly, however, when trying to create stored procedures, a MySqlException is thrown when trying to redefine the DELIMITER MySql.Data.MySqlClient.MySqlException was unhandled Message="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" Source="MySql.Data" ErrorCode=-2147467259 Number=1064 StackTrace: à MySql.Data.MySqlClient.MySqlStream.ReadPacket() à MySql.Data.MySqlClient.NativeDriver.ReadResult(UInt64& affectedRows, Int64& lastInsertId) à MySql.Data.MySqlClient.MySqlDataReader.GetResultSet() à MySql.Data.MySqlClient.MySqlDataReader.NextResult() à MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) à MySql.Data.MySqlClient.MySqlCommand.ExecuteReader() à MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() à MySql.Data.MySqlClient.MySqlScript.Execute() Is it the expected behaviour? I really don't want to parse the sql file myself to find blocks with a delimiter. How to repeat: - create a stored procedure for any database - store it in a sql file : storedproc.sql - use .Net connector - execute this code using (MySqlConnection connection = new MySqlConnection(cnxString)) { connection.Open(); MySqlScript script = new MySqlScript(connection, File.ReadAllText(@"storedproc.sql")); // throws the exception script.Execute(); Console.WriteLine(rows); }