Bug #44349 | Connector/Net 5.2.5 ignores parameter names | ||
---|---|---|---|
Submitted: | 17 Apr 2009 20:07 | Modified: | 30 Apr 2009 13:35 |
Reporter: | Julian Beckensall | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | Connector / NET | Severity: | S2 (Serious) |
Version: | 5.2.5 | OS: | Any |
Assigned to: | Reggie Burnett | CPU Architecture: | Any |
Tags: | connector, parameter names |
[17 Apr 2009 20:07]
Julian Beckensall
[20 Apr 2009 8:44]
Tonci Grgin
Hi Julian and thanks for your report. I can't gather much about the problem from your words so if you can come up with simple test case (incl. DDL/DML) that I can load into VS2005/8 I will take a look.
[20 Apr 2009 10:39]
Julian Beckensall
Hi Tonci. Sorry - should have supplied this originally. Stored proc: - ---------------------------------------- DELIMITER $$ DROP PROCEDURE IF EXISTS `XXXXXX`.`spParamTest` $$ CREATE PROCEDURE `XXXXXX`.`spParamTest` (p_1 varchar(5), p_2 varchar(5)) BEGIN select p_1 as P1, p_2 as P2; END $$ DELIMITER ; ---------------------------------------- VS2005 C# Code: - ---------------------------------------- using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using MySql.Data.MySqlClient; // Version 5.2.5.0 (Runtime = v2.0.50727) namespace paramTest { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { // Connection String // Need "Use Procedure Bodies =false" as I don't have access to the "procs" table // Server is a remote, Linux server // ASP.Net code running on my XP PC but behaves the same on Win2003 server string connstr = "Database=XXXXX;Data Source=###.###.###.###;User Id=XXXXX;Password=XXXXX; Use Procedure Bodies =false;"; // Open connection MySqlConnection conn = new MySqlConnection(connstr); conn.Open(); MySqlCommand cmd = new MySqlCommand("spParamTest", conn); cmd.CommandType = CommandType.StoredProcedure; // Add Params in the 'wrong' order cmd.Parameters.AddWithValue("p_2", "World"); cmd.Parameters.AddWithValue("p_1", "Hello"); // Get Adapter MySqlDataAdapter adapter = new MySqlDataAdapter(cmd); // Create + Populate Dataset DataSet dataset = new DataSet(); adapter.Fill(dataset); // Show return values - should be "P1: Hello", "P2: World" Response.Write("P1: " + dataset.Tables[0].Rows[0]["P1"].ToString()); Response.Write("<br/>"); Response.Write("P2: " + dataset.Tables[0].Rows[0]["P2"].ToString()); // Tidy up conn.Close(); conn = null; dataset = null; } } }
[20 Apr 2009 13:47]
Tonci Grgin
Julian, your parameters have no sense of direction :-) Have you tried defining: o in SP: IN p_1 varchar(5), IN p_2 varchar(5) o in C#: cmd.Parameters[0].Direction = ParameterDirection.Input; cmd.Parameters[1].Direction = ParameterDirection.Input; Does the test work if all is defined like this? How does, if you can test it, "Use Procedure Bodies = true" change things?
[20 Apr 2009 13:58]
Tonci Grgin
This works as expected: cmdCreateTable.CommandText = ("CREATE PROCEDURE `SP_BUG44349`(" + "\n" + "IN p_1 VARCHAR(5), \n" + "IN p_2 VARCHAR(5) \n" + ") \n" + "BEGIN SELECT p_1 AS P1, p_2 AS P2; END\n"); try { cmdCreateTable.ExecuteNonQuery(); MySqlCommand cmd = new MySqlCommand("SP_BUG44349", conn); cmd.CommandTimeout = 0; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("?p_1", ("Hello")); cmd.Parameters[0].DbType = DbType.AnsiString; cmd.Parameters[0].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("?p_2", ("world")); cmd.Parameters[1].DbType = DbType.AnsiString; cmd.Parameters[1].Direction = ParameterDirection.Input; MySqlDataAdapter adapter = new MySqlDataAdapter(cmd); DataSet dataset = new DataSet(); adapter.Fill(dataset); Console.WriteLine("P1: " + dataset.Tables[0].Rows[0]["P1"].ToString()); Console.WriteLine("P2: " + dataset.Tables[0].Rows[0]["P2"].ToString()); dataset = null; against remote MySQL server 5.1.31 on OpenSolaris host. .NET FW used is 3.5.
[20 Apr 2009 14:24]
Julian Beckensall
Hi again Tonci. The code you supplied does work, but only because you create the parameters in the correct order in the ASP code. If I change your code to this (adding p_2, THEN p_1), it doesn't: - cmd.Parameters.AddWithValue("?p_2", ("world")); cmd.Parameters[0].DbType = DbType.AnsiString; cmd.Parameters[0].Direction = ParameterDirection.Input; cmd.Parameters.AddWithValue("?p_1", ("Hello")); cmd.Parameters[1].DbType = DbType.AnsiString; cmd.Parameters[1].Direction = ParameterDirection.Input; In other words, it seems to ignore the parameter names and goes by the order in which they were added to the Command object. I have tried to connect without the "Use Procedure Bodies = false", but I get this error: "SELECT command denied to user 'XXXXX'@'XXXXX.com' for table 'proc'". As this database is controlled by the ISP, I don't seem to have any choice but to use it. Thanks for your help. Julian.
[20 Apr 2009 14:51]
Tonci Grgin
Julian, you are right. Verified as described with test case already pasted. Replacing cmd.Parameters.AddWithValue("?p_1", ("Hello")); and cmd.Parameters.AddWithValue("?p_2", ("Hello")); shows the problem: [20.4.2009 16:48:48] - Executing command QUERY with text ='call SP_BUG44349 ('world', 'Hello')' P1: world P2: Hello
[30 Apr 2009 13:35]
Reggie Burnett
This is expected behavior when you use 'use procedure bodies=false'. The reason is that when we don't have access to the procedure bodies the connector cannot determine what the parameters for a proc are. In that case, the connector has no choice but to use the parameters in the order they are added to the command. this is actually a fairly nice optimization. As long as you add the parameters in the right order you avoid a round trip to the server to get parameter names which speeds things up.