Closed
Description
Steps To Reproduce
- Open a connection to a MySql Server without the Database parameter in int.
- Create a database.
- Create a table.
- Create a stored procedure.
- Execute the stored procedure.
Observed
When calling stored procedures, if the database is not provided in the connection string, the execution will fail saying Incorrect number of arguments for PROCEDURE <procedure name>; expected N, got M
message. After testing a lot, we saw the problem disappears when the database name is provided.
Tested against
MySql Server 5.7.17
MySql Server 5.7.18
MySqlConnector 0.21.0 0.20.2 0.20.1 0.20.0
Notes
Just in case, we ran the test using the oracle connector and both test passed successfully. This is not priority for us, but we found the error writing stored procedure tests.
MSTest Code
using System;
using System.Data;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MySql.Data.MySqlClient;
namespace MySqlStoredProcedureError
{
[TestClass]
public class StoredProcedureTest
{
[TestMethod]
public void ShouldExecuteWithDatabaseOnConnectionString()
{
using (var connection = new MySqlConnection("Server=localhost;Database=test;User=test;Password=test1234;Connection Timeout=3600;Allow User Variables=True;POOLING=true"))
{
this.CreateDatabase(connection);
this.CreateTable(connection);
this.CreateStoredProcedure(connection);
this.ExecuteProcedure(connection);
this.DropDatabase(connection);
}
}
[TestMethod]
public void ShouldExecuteWithoutDatabaseOnConnectionString()
{
using (var connection = new MySqlConnection("Server=localhost;User=test;Password=test1234;Connection Timeout=3600;Allow User Variables=True;POOLING=true"))
{
this.CreateDatabase(connection);
this.CreateTable(connection);
this.CreateStoredProcedure(connection);
this.ExecuteProcedure(connection);
this.DropDatabase(connection);
}
}
private void CreateDatabase(MySqlConnection connection)
{
using (var command = this.GetCommand(connection, this.GetDatabaseCreation()))
{
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
private void CreateTable(MySqlConnection connection)
{
using (var command = this.GetCommand(connection, this.GetTableCreation()))
{
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
private void CreateStoredProcedure(MySqlConnection connection)
{
using (var command = this.GetCommand(connection, this.GetStoredProcedureCreation()))
{
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
private void ExecuteProcedure(MySqlConnection connection)
{
using (var command = this.GetCommand(connection, "SearchTestTable"))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@Name", "John");
command.ExecuteNonQuery();
}
}
private void DropDatabase(MySqlConnection connection)
{
using (var command = this.GetCommand(connection, this.GetDropDatabase()))
{
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
private MySqlCommand GetCommand(MySqlConnection connection, string commandText)
{
var command = connection.CreateCommand() as MySqlCommand;
if (connection.State != ConnectionState.Open)
connection.Open();
command.CommandText = commandText;
return command;
}
private string GetDatabaseCreation()
{
return @"
CREATE DATABASE IF NOT EXISTS `test`;
USE `test`;
";
}
private string GetDropDatabase()
{
return @"
DROP DATABASE IF EXISTS `test`;
";
}
private string GetTableCreation()
{
return @"
CREATE TABLE IF NOT EXISTS `test`.`testtable`
(
`Id` INT NOT NULL AUTO_INCREMENT,
`Name` NVARCHAR(200) NOT NULL,
`IsActive` BOOL NOT NULL,
`Amount` DECIMAL(20,9) NOT NULL,
`CreatedDate` DATETIME NOT NULL,
CONSTRAINT `PK_TestTableTable` PRIMARY KEY (`Id` ASC),
CONSTRAINT `UX_TestTableTable_Name` UNIQUE (`Name`)
)ENGINE=INNODB;
";
}
private string GetStoredProcedureCreation()
{
return @"
DROP PROCEDURE IF EXISTS `SearchTestTable`;
CREATE PROCEDURE `SearchTestTable`
(
`Name` VARCHAR(200)
)
BEGIN
SELECT *
FROM `test`.`testtable` t
WHERE t.`Name` = `Name`;
END
";
}
}
}