You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1294 lines
50 KiB
1294 lines
50 KiB
15 years ago
|
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
|
||
|
//
|
||
|
// This program is free software; you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU General Public License version 2 as published by
|
||
|
// the Free Software Foundation
|
||
|
//
|
||
|
// There are special exceptions to the terms and conditions of the GPL
|
||
|
// as it is applied to this software. View the full text of the
|
||
|
// exception in file EXCEPTIONS in the directory of this software
|
||
|
// distribution.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
// GNU General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU General Public License
|
||
|
// along with this program; if not, write to the Free Software
|
||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
|
||
|
using System;
|
||
|
using System.Data;
|
||
|
using MySql.Data.MySqlClient;
|
||
|
using NUnit.Framework;
|
||
|
using System.Globalization;
|
||
|
using System.Threading;
|
||
|
using MySql.Data.Types;
|
||
|
using System.Data.Common;
|
||
|
|
||
|
namespace MySql.Data.MySqlClient.Tests
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Summary description for StoredProcedure.
|
||
|
/// </summary>
|
||
|
[TestFixture]
|
||
|
public class StoredProcedure : BaseTest
|
||
|
{
|
||
|
private static string fillError = null;
|
||
|
|
||
|
public StoredProcedure()
|
||
|
{
|
||
|
csAdditions = ";procedure cache size=0;";
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #7623 Adding MySqlParameter causes error if MySqlDbType is Decimal
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void ReturningResultset()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest(val decimal(10,3)) begin select val; end");
|
||
|
|
||
|
using (MySqlCommand cmd = new MySqlCommand("spTest", conn))
|
||
|
{
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
|
||
|
MySqlParameter p = cmd.Parameters.Add("?val", MySqlDbType.Decimal);
|
||
|
p.Precision = 10;
|
||
|
p.Scale = 3;
|
||
|
p.Value = 21;
|
||
|
|
||
|
decimal id = (decimal)cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(21, id);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void NonQuery()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE TABLE Test(id INT, name VARCHAR(20))");
|
||
|
execSQL(@"CREATE PROCEDURE spTest(IN value INT)
|
||
|
BEGIN INSERT INTO Test VALUES(value, 'Test'); END");
|
||
|
|
||
|
//setup testing data
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?value", 2);
|
||
|
int rowsAffected = cmd.ExecuteNonQuery();
|
||
|
Assert.AreEqual(1, rowsAffected);
|
||
|
|
||
|
cmd.CommandText = "SELECT * FROM Test";
|
||
|
cmd.CommandType = CommandType.Text;
|
||
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||
|
{
|
||
|
Assert.IsTrue(reader.Read());
|
||
|
Assert.AreEqual(2, reader.GetInt32(0));
|
||
|
Assert.AreEqual("Test", reader.GetString(1));
|
||
|
Assert.IsFalse(reader.Read());
|
||
|
Assert.IsFalse(reader.NextResult());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #17814 Stored procedure fails unless DbType set explicitly
|
||
|
/// Bug #23749 VarChar field size over 255 causes a System.OverflowException
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void OutputParameters()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// we don't want to run this test under no access
|
||
|
string connInfo = GetConnectionInfo();
|
||
|
if (connInfo.IndexOf("use procedure bodies=false") != -1) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest(out value VARCHAR(350), OUT intVal INT, " +
|
||
|
"OUT dateVal TIMESTAMP, OUT floatVal FLOAT, OUT noTypeVarChar VARCHAR(20), " +
|
||
|
"OUT noTypeInt INT) " +
|
||
|
"BEGIN SET value='42'; SET intVal=33; SET dateVal='2004-06-05 07:58:09'; " +
|
||
|
"SET floatVal = 1.2; SET noTypeVarChar='test'; SET noTypeInt=66; END");
|
||
|
|
||
|
// we use rootConn here since we are using parameters
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.Add(new MySqlParameter("?value", MySqlDbType.VarChar));
|
||
|
cmd.Parameters.Add(new MySqlParameter("?intVal", MySqlDbType.Int32));
|
||
|
cmd.Parameters.Add(new MySqlParameter("?dateVal", MySqlDbType.DateTime));
|
||
|
cmd.Parameters.Add(new MySqlParameter("?floatVal", MySqlDbType.Float));
|
||
|
MySqlParameter vcP = new MySqlParameter();
|
||
|
vcP.ParameterName = "?noTypeVarChar";
|
||
|
vcP.Direction = ParameterDirection.Output;
|
||
|
cmd.Parameters.Add(vcP);
|
||
|
MySqlParameter vcI = new MySqlParameter();
|
||
|
vcI.ParameterName = "?noTypeInt";
|
||
|
vcI.Direction = ParameterDirection.Output;
|
||
|
cmd.Parameters.Add(vcI);
|
||
|
cmd.Parameters[0].Direction = ParameterDirection.Output;
|
||
|
cmd.Parameters[1].Direction = ParameterDirection.Output;
|
||
|
cmd.Parameters[2].Direction = ParameterDirection.Output;
|
||
|
cmd.Parameters[3].Direction = ParameterDirection.Output;
|
||
|
int rowsAffected = cmd.ExecuteNonQuery();
|
||
|
|
||
|
Assert.AreEqual(0, rowsAffected);
|
||
|
Assert.AreEqual("42", cmd.Parameters[0].Value);
|
||
|
Assert.AreEqual(33, cmd.Parameters[1].Value);
|
||
|
Assert.AreEqual(new DateTime(2004, 6, 5, 7, 58, 9),
|
||
|
Convert.ToDateTime(cmd.Parameters[2].Value));
|
||
|
Assert.AreEqual(1.2, (decimal)(float)cmd.Parameters[3].Value);
|
||
|
Assert.AreEqual("test", cmd.Parameters[4].Value);
|
||
|
Assert.AreEqual(66, cmd.Parameters[5].Value);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void NoBatch()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest;select * from Test", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.ExecuteNonQuery();
|
||
|
Assert.Fail("Should have thrown an exception");
|
||
|
}
|
||
|
catch (Exception)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void WrongParameters()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest(p1 INT) BEGIN SELECT 1; END");
|
||
|
try
|
||
|
{
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?p2", 1);
|
||
|
cmd.ExecuteNonQuery();
|
||
|
Assert.Fail("Should have thrown an exception");
|
||
|
}
|
||
|
catch (Exception)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void NoInOutMarker()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest( valin varchar(50) ) BEGIN SELECT valin; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?valin", "myvalue");
|
||
|
object val = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual("myvalue", val);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void InputOutputParameters()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest( INOUT strVal VARCHAR(50), INOUT numVal INT, OUT outVal INT UNSIGNED ) " +
|
||
|
"BEGIN SET strVal = CONCAT(strVal,'ending'); SET numVal=numVal * 2; SET outVal=99; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?strVal", "beginning");
|
||
|
cmd.Parameters.AddWithValue("?numVal", 33);
|
||
|
cmd.Parameters.AddWithValue("?outVal", MySqlDbType.Int32);
|
||
|
cmd.Parameters[0].Direction = ParameterDirection.InputOutput;
|
||
|
cmd.Parameters[1].Direction = ParameterDirection.InputOutput;
|
||
|
cmd.Parameters[2].Direction = ParameterDirection.Output;
|
||
|
int rowsAffected = cmd.ExecuteNonQuery();
|
||
|
Assert.AreEqual(0, rowsAffected);
|
||
|
Assert.AreEqual("beginningending", cmd.Parameters[0].Value);
|
||
|
Assert.AreEqual(66, cmd.Parameters[1].Value);
|
||
|
Assert.AreEqual(99, cmd.Parameters[2].Value);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void NoSPOnPre50()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.ExecuteNonQuery();
|
||
|
Assert.Fail("This should not have worked");
|
||
|
}
|
||
|
catch (Exception)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void ExecuteScalar()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest( IN valin VARCHAR(50), OUT valout VARCHAR(50) ) " +
|
||
|
"BEGIN SET valout=valin; SELECT 'Test'; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?valin", "valuein");
|
||
|
cmd.Parameters.Add(new MySqlParameter("?valout", MySqlDbType.VarChar));
|
||
|
cmd.Parameters[1].Direction = ParameterDirection.Output;
|
||
|
object result = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual("Test", result);
|
||
|
Assert.AreEqual("valuein", cmd.Parameters[1].Value);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #13590 ExecuteScalar returns only Int64 regardless of actual SQL type
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void ExecuteScalar2()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest() " +
|
||
|
"BEGIN DECLARE myVar1 INT; SET myVar1 := 1; SELECT myVar1; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
object result = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(1, result);
|
||
|
Assert.IsTrue(result is Int32);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void ExecuteReader()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest(OUT p INT) " +
|
||
|
"BEGIN SELECT 1; SET p=2; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.Parameters.Add("?p", MySqlDbType.Int32);
|
||
|
cmd.Parameters[0].Direction = ParameterDirection.Output;
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||
|
{
|
||
|
Assert.AreEqual(true, reader.Read());
|
||
|
Assert.AreEqual(false, reader.NextResult());
|
||
|
Assert.AreEqual(false, reader.Read());
|
||
|
}
|
||
|
Assert.AreEqual(2, cmd.Parameters[0].Value);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void MultipleResultsets()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
MultipleResultsetsImpl(false);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void MultipleResultsetsPrepared()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
MultipleResultsetsImpl(true);
|
||
|
}
|
||
|
|
||
|
private void MultipleResultsetsImpl(bool prepare)
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest() " +
|
||
|
"BEGIN SELECT 1; SELECT 2; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
if (prepare) cmd.Prepare();
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
MySqlDataReader reader = cmd.ExecuteReader();
|
||
|
Assert.AreEqual(true, reader.Read());
|
||
|
Assert.AreEqual(true, reader.NextResult());
|
||
|
Assert.AreEqual(true, reader.Read());
|
||
|
Assert.AreEqual(false, reader.NextResult());
|
||
|
Assert.AreEqual(false, reader.Read());
|
||
|
reader.Close();
|
||
|
|
||
|
DataSet ds = new DataSet();
|
||
|
MySqlCommand cmd2 = new MySqlCommand("spTest", conn);
|
||
|
cmd2.CommandType = CommandType.StoredProcedure;
|
||
|
MySqlDataAdapter da = new MySqlDataAdapter(cmd2);
|
||
|
da.FillError += new FillErrorEventHandler(da_FillError);
|
||
|
fillError = null;
|
||
|
da.Fill(ds);
|
||
|
Assert.AreEqual(2, ds.Tables.Count);
|
||
|
Assert.AreEqual(1, ds.Tables[0].Rows.Count);
|
||
|
Assert.AreEqual(1, ds.Tables[1].Rows.Count);
|
||
|
Assert.AreEqual(1, ds.Tables[0].Rows[0][0]);
|
||
|
Assert.AreEqual(2, ds.Tables[1].Rows[0][0]);
|
||
|
Assert.IsNull(fillError);
|
||
|
}
|
||
|
|
||
|
private static void da_FillError(object sender, FillErrorEventArgs e)
|
||
|
{
|
||
|
fillError = e.Errors.Message;
|
||
|
e.Continue = true;
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void FunctionNoParams()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE FUNCTION fnTest() RETURNS CHAR(50)" +
|
||
|
" LANGUAGE SQL DETERMINISTIC BEGIN RETURN \"Test\"; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("SELECT fnTest()", conn);
|
||
|
cmd.CommandType = CommandType.Text;
|
||
|
object result = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual("Test", result);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void FunctionParams()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE FUNCTION fnTest( val1 INT, val2 CHAR(40) ) RETURNS INT " +
|
||
|
" LANGUAGE SQL DETERMINISTIC BEGIN RETURN val1 + LENGTH(val2); END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("SELECT fnTest(22, 'Test')", conn);
|
||
|
cmd.CommandType = CommandType.Text;
|
||
|
object result = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(26, result);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void ExecuteWithCreate()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
string sql = "CREATE PROCEDURE spTest(IN var INT) BEGIN SELECT var; END; call spTest(?v)";
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand(sql, conn);
|
||
|
cmd.Parameters.Add(new MySqlParameter("?v", 33));
|
||
|
object val = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(33, val);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #9722 Connector does not recognize parameters separated by a linefeed
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void OtherProcSigs()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest(IN \r\nvalin DECIMAL(10,2),\nIN val2 INT) " +
|
||
|
"SQL SECURITY INVOKER BEGIN SELECT valin; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?valin", 20.4);
|
||
|
cmd.Parameters.AddWithValue("?val2", 4);
|
||
|
decimal val = (decimal)cmd.ExecuteScalar();
|
||
|
Decimal d = new Decimal(20.4);
|
||
|
Assert.AreEqual(d, val);
|
||
|
|
||
|
// create our second procedure
|
||
|
execSQL("DROP PROCEDURE IF EXISTS spTest");
|
||
|
execSQL("CREATE PROCEDURE spTest( \r\n) BEGIN SELECT 4; END");
|
||
|
cmd.Parameters.Clear();
|
||
|
object val1 = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(4, val1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #10644 Cannot call a stored function directly from Connector/Net
|
||
|
/// Bug #25013 Return Value parameter not found
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void CallingStoredFunctionasProcedure()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE FUNCTION fnTest(valin int) RETURNS INT " +
|
||
|
" LANGUAGE SQL DETERMINISTIC BEGIN return valin * 2; END");
|
||
|
MySqlCommand cmd = new MySqlCommand("fnTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?valin", 22);
|
||
|
MySqlParameter retVal = cmd.CreateParameter();
|
||
|
retVal.ParameterName = "?retval";
|
||
|
retVal.MySqlDbType = MySqlDbType.Int32;
|
||
|
retVal.Direction = ParameterDirection.ReturnValue;
|
||
|
cmd.Parameters.Add(retVal);
|
||
|
cmd.ExecuteNonQuery();
|
||
|
Assert.AreEqual(44, cmd.Parameters[1].Value);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #11450 Connector/Net, current database and stored procedures
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void NoDefaultDatabase()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest() BEGIN SELECT 4; END");
|
||
|
|
||
|
string newConnStr = GetConnectionString(false);
|
||
|
using (MySqlConnection c = new MySqlConnection(newConnStr))
|
||
|
{
|
||
|
c.Open();
|
||
|
MySqlCommand cmd2 = new MySqlCommand(String.Format("use `{0}`", database0), c);
|
||
|
cmd2.ExecuteNonQuery();
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", c);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
object val = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(4, val);
|
||
|
|
||
|
cmd2.CommandText = String.Format("use `{0}`", database1);
|
||
|
cmd2.ExecuteNonQuery();
|
||
|
|
||
|
cmd.CommandText = String.Format("`{0}`.spTest", database0);
|
||
|
val = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(4, val);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #13590 ExecuteScalar returns only Int64 regardless of actual SQL type
|
||
|
/// </summary>
|
||
|
/* [Test]
|
||
|
public void TestSelectingInts()
|
||
|
{
|
||
|
execSQL("CREATE PROCEDURE spTest() BEGIN DECLARE myVar INT; " +
|
||
|
"SET MyVar := 1; SELECT CAST(myVar as SIGNED); END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
object val = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(1, val, "Checking value");
|
||
|
Assert.IsTrue(val is Int32, "Checking type");
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #11386 Numeric parameters with Precision and Scale not taken into account by Connector
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void DecimalAsParameter()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest(IN d DECIMAL(19,4)) BEGIN SELECT d; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?d", 21);
|
||
|
decimal d = (decimal)cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(21, d);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #6902 Errors in parsing stored procedure parameters
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void ParmWithCharacterSet()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest(P longtext character set utf8) " +
|
||
|
"BEGIN SELECT P; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?P", "This is my value");
|
||
|
string p = (string)cmd.ExecuteScalar();
|
||
|
Assert.AreEqual("This is my value", p);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #13753 Exception calling stored procedure with special characters in parameters
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void SpecialCharacters()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("SET sql_mode=ANSI_QUOTES");
|
||
|
try
|
||
|
{
|
||
|
execSQL("CREATE PROCEDURE spTest(\"@Param1\" text) BEGIN SELECT \"@Param1\"; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.Parameters.AddWithValue("?@Param1", "This is my value");
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
|
||
|
string val = (string)cmd.ExecuteScalar();
|
||
|
Assert.AreEqual("This is my value", val);
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
execSQL("SET sql_mode=\"\"");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void CallingSPWithPrepare()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest(P int) BEGIN SELECT P; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?P", 33);
|
||
|
cmd.Prepare();
|
||
|
|
||
|
int p = (int)cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(33, p);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #13927 Multiple Records to same Table in Transaction Problem
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void MultipleRecords()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE TABLE Test (id INT, name VARCHAR(20))");
|
||
|
execSQL("CREATE PROCEDURE spTest(id int, str VARCHAR(45)) " +
|
||
|
"BEGIN INSERT INTO Test VALUES(id, str); END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
|
||
|
cmd.Parameters.AddWithValue("?id", 1);
|
||
|
cmd.Parameters.AddWithValue("?str", "First record");
|
||
|
cmd.ExecuteNonQuery();
|
||
|
|
||
|
cmd.Parameters.Clear();
|
||
|
cmd.Parameters.AddWithValue("?id", 2);
|
||
|
cmd.Parameters.AddWithValue("?str", "Second record");
|
||
|
cmd.ExecuteNonQuery();
|
||
|
|
||
|
MySqlDataAdapter da = new MySqlDataAdapter("SELECT * FROM Test", conn);
|
||
|
DataTable dt = new DataTable();
|
||
|
da.Fill(dt);
|
||
|
|
||
|
Assert.AreEqual(1, dt.Rows[0]["id"]);
|
||
|
Assert.AreEqual(2, dt.Rows[1]["id"]);
|
||
|
Assert.AreEqual("First record", dt.Rows[0]["name"]);
|
||
|
Assert.AreEqual("Second record", dt.Rows[1]["name"]);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #16788 Only byte arrays and strings can be serialized by MySqlBinary
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void Bug16788()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE TABLE Test (id integer(9), state varchar(2))");
|
||
|
execSQL("CREATE PROCEDURE spTest(IN p1 integer(9), IN p2 varchar(2)) " +
|
||
|
"BEGIN " +
|
||
|
"INSERT INTO Test (id, state) VALUES (p1, p2); " +
|
||
|
"END");
|
||
|
|
||
|
MySqlCommand cmd = conn.CreateCommand();
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.CommandText = "spTest";
|
||
|
cmd.Parameters.Add("?p1", MySqlDbType.UInt16, 9);
|
||
|
cmd.Parameters["?p1"].Value = 44;
|
||
|
cmd.Parameters.Add("?p2", MySqlDbType.VarChar, 2);
|
||
|
cmd.Parameters["?p2"].Value = "ss";
|
||
|
cmd.ExecuteNonQuery();
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void ReturningEmptyResultSet()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE TABLE test1 (id int AUTO_INCREMENT NOT NULL, " +
|
||
|
"Name VARCHAR(100) NOT NULL, PRIMARY KEY(id))");
|
||
|
execSQL("CREATE TABLE test2 (id int AUTO_INCREMENT NOT NULL, " +
|
||
|
"id1 INT NOT NULL, id2 INT NOT NULL, PRIMARY KEY(id))");
|
||
|
|
||
|
execSQL("INSERT INTO test1 (Id, Name) VALUES (1, 'Item1')");
|
||
|
execSQL("INSERT INTO test1 (Id, Name) VALUES (2, 'Item2')");
|
||
|
execSQL("INSERT INTO test2 (Id, Id1, Id2) VALUES (1, 1, 1)");
|
||
|
execSQL("INSERT INTO test2 (Id, Id1, Id2) VALUES (2, 2, 1)");
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest(Name VARCHAR(100), OUT Table1Id INT) " +
|
||
|
"BEGIN SELECT t1.Id INTO Table1Id FROM test1 t1 WHERE t1.Name LIKE Name; " +
|
||
|
"SELECT t3.Id2 FROM test2 t3 WHERE t3.Id1 = Table1Id; END");
|
||
|
|
||
|
MySqlCommand cmd = conn.CreateCommand();
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.CommandText = "spTest";
|
||
|
cmd.Parameters.AddWithValue("?Name", "Item3");
|
||
|
cmd.Parameters.Add("?Table1Id", MySqlDbType.Int32);
|
||
|
cmd.Parameters["?Table1Id"].Direction = ParameterDirection.Output;
|
||
|
|
||
|
DataSet ds = new DataSet();
|
||
|
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
|
||
|
try
|
||
|
{
|
||
|
da.Fill(ds);
|
||
|
}
|
||
|
catch (MySqlException)
|
||
|
{
|
||
|
// on 5.1 this throws an exception that no rows were returned.
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if !CF
|
||
|
[Explicit]
|
||
|
[Test]
|
||
|
public void ProcedureCache()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// open a new connection using a procedure cache
|
||
|
string connStr = GetConnectionString(true);
|
||
|
connStr += ";procedure cache size=25;logging=true";
|
||
|
using (MySqlConnection c = new MySqlConnection(connStr))
|
||
|
{
|
||
|
c.Open();
|
||
|
|
||
|
// install our custom trace listener
|
||
|
GenericListener myListener = new GenericListener();
|
||
|
System.Diagnostics.Trace.Listeners.Add(myListener);
|
||
|
|
||
|
for (int x = 0; x < 10; x++)
|
||
|
{
|
||
|
execSQL("CREATE PROCEDURE spTest" + x + "() BEGIN SELECT 1; END");
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest" + x, c);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
for (int y = 0; y < 20; y++)
|
||
|
{
|
||
|
cmd.ExecuteNonQuery();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// remove our custom trace listener
|
||
|
System.Diagnostics.Trace.Listeners.Remove(myListener);
|
||
|
|
||
|
// now see how many times our listener recorded a cache hit
|
||
|
Assert.AreEqual(190, myListener.Find("from procedure cache"));
|
||
|
Assert.AreEqual(10, myListener.Find("from server"));
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #20581 Null Reference Exception when closing reader after stored procedure.
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void Bug20581()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest(p int) BEGIN SELECT p; END");
|
||
|
MySqlParameter param1;
|
||
|
MySqlCommand command = new MySqlCommand("spTest", conn);
|
||
|
command.CommandType = CommandType.StoredProcedure;
|
||
|
|
||
|
param1 = command.Parameters.Add("?p", MySqlDbType.Int32);
|
||
|
param1.Value = 3;
|
||
|
|
||
|
command.Prepare();
|
||
|
using (MySqlDataReader reader = command.ExecuteReader())
|
||
|
{
|
||
|
reader.Read();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #17046 Null pointer access when stored procedure is used
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void PreparedReader()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE TABLE Test (id int(10) unsigned NOT NULL default '0', " +
|
||
|
"val int(10) unsigned default NULL, PRIMARY KEY (id)) " +
|
||
|
"ENGINE=InnoDB DEFAULT CHARSET=utf8");
|
||
|
execSQL("CREATE PROCEDURE spTest (IN pp INTEGER) " +
|
||
|
"select * from Test where id > pp ");
|
||
|
|
||
|
MySqlCommand c = new MySqlCommand("spTest", conn);
|
||
|
c.CommandType = CommandType.StoredProcedure;
|
||
|
IDataParameter p = c.CreateParameter();
|
||
|
p.ParameterName = "?pp";
|
||
|
p.Value = 10;
|
||
|
c.Parameters.Add(p);
|
||
|
c.Prepare();
|
||
|
using (MySqlDataReader reader = c.ExecuteReader())
|
||
|
{
|
||
|
while (reader.Read())
|
||
|
{
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void UnsignedOutputParameters()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE TABLE Test (id INT(10) UNSIGNED AUTO_INCREMENT, PRIMARY KEY (id)) ");
|
||
|
execSQL("CREATE PROCEDURE spTest (OUT id BIGINT UNSIGNED) " +
|
||
|
"BEGIN INSERT INTO Test VALUES (NULL); SET id=LAST_INSERT_ID(); END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.Add("?id", MySqlDbType.UInt64);
|
||
|
cmd.Parameters[0].Direction = ParameterDirection.Output;
|
||
|
cmd.ExecuteNonQuery();
|
||
|
|
||
|
object o = cmd.Parameters[0].Value;
|
||
|
Assert.IsTrue(o is ulong);
|
||
|
Assert.AreEqual(1, o);
|
||
|
}
|
||
|
|
||
|
#if !CF
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #22452 MySql.Data.MySqlClient.MySqlException:
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void TurkishStoredProcs()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest(IN p_paramname INT) BEGIN SELECT p_paramname; END");
|
||
|
CultureInfo uiCulture = Thread.CurrentThread.CurrentUICulture;
|
||
|
CultureInfo culture = Thread.CurrentThread.CurrentCulture;
|
||
|
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");
|
||
|
Thread.CurrentThread.CurrentUICulture = new CultureInfo("tr-TR");
|
||
|
|
||
|
try
|
||
|
{
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.Parameters.AddWithValue("?p_paramname", 2);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.ExecuteScalar();
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
Thread.CurrentThread.CurrentCulture = culture;
|
||
|
Thread.CurrentThread.CurrentUICulture = uiCulture;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #23268 System.FormatException when invoking procedure with ENUM input parameter
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void ProcEnumParamTest()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE TABLE Test(str VARCHAR(50), e ENUM ('P','R','F','E'), i INT(6))");
|
||
|
execSQL("CREATE PROCEDURE spTest(IN p_enum ENUM('P','R','F','E')) BEGIN " +
|
||
|
"INSERT INTO Test (str, e, i) VALUES (null, p_enum, 55); END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?p_enum", "P");
|
||
|
cmd.Parameters["?p_enum"].Direction = ParameterDirection.Input;
|
||
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||
|
{
|
||
|
}
|
||
|
cmd.CommandText = "SELECT e FROM Test";
|
||
|
cmd.CommandType = CommandType.Text;
|
||
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||
|
{
|
||
|
reader.Read();
|
||
|
Assert.AreEqual("P", reader.GetString(0));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #25625 Crashes when calling with CommandType set to StoredProcedure
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void RunWithoutSelectPrivsThrowException()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// we don't want this test to run in our all access fixture
|
||
|
string connInfo = GetConnectionInfo();
|
||
|
if (connInfo.IndexOf("use procedure bodies=false") == -1)
|
||
|
return;
|
||
|
|
||
|
suExecSQL(String.Format(
|
||
|
"GRANT ALL ON `{0}`.* to 'testuser'@'%' identified by 'testuser'",
|
||
|
database0));
|
||
|
suExecSQL(String.Format(
|
||
|
"GRANT ALL ON `{0}`.* to 'testuser'@'localhost' identified by 'testuser'",
|
||
|
database0));
|
||
|
|
||
|
execSQL("DROP PROCEDURE IF EXISTS spTest");
|
||
|
execSQL("CREATE PROCEDURE spTest(id int, OUT outid int, INOUT inoutid int) " +
|
||
|
"BEGIN SET outid=id+inoutid; SET inoutid=inoutid+id; END");
|
||
|
|
||
|
string s = GetConnectionString("testuser", "testuser", true);
|
||
|
MySqlConnection c = new MySqlConnection(s);
|
||
|
c.Open();
|
||
|
|
||
|
try
|
||
|
{
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", c);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?id", 2);
|
||
|
cmd.Parameters.AddWithValue("?outid", MySqlDbType.Int32);
|
||
|
cmd.Parameters[1].Direction = ParameterDirection.Output;
|
||
|
cmd.Parameters.AddWithValue("?inoutid", 4);
|
||
|
cmd.Parameters[2].Direction = ParameterDirection.InputOutput;
|
||
|
cmd.ExecuteNonQuery();
|
||
|
|
||
|
Assert.AreEqual(6, cmd.Parameters[1].Value);
|
||
|
Assert.AreEqual(6, cmd.Parameters[2].Value);
|
||
|
}
|
||
|
catch (InvalidOperationException iex)
|
||
|
{
|
||
|
Assert.IsTrue(iex.Message.StartsWith("Unable to retrieve"));
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
if (c != null)
|
||
|
c.Close();
|
||
|
suExecSQL("DELETE FROM mysql.user WHERE user = 'testuser'");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void CallingFunctionWithoutReturnParameter()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE FUNCTION fnTest (p_kiosk bigint(20), " +
|
||
|
"p_user bigint(20)) returns double begin declare v_return double; " +
|
||
|
"set v_return = 3.6; return v_return; end");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("fnTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?p_kiosk", 2);
|
||
|
cmd.Parameters.AddWithValue("?p_user", 4);
|
||
|
cmd.ExecuteNonQuery();
|
||
|
Assert.AreEqual(2, cmd.Parameters.Count);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #25609 MySqlDataAdapter.FillSchema
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void GetSchema()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest() BEGIN SELECT * FROM Test; END");
|
||
|
execSQL(@"CREATE TABLE Test(id INT AUTO_INCREMENT, name VARCHAR(20), PRIMARY KEY (id)) ");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
|
||
|
MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly);
|
||
|
reader.Read();
|
||
|
reader.Close();
|
||
|
|
||
|
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
|
||
|
DataTable schema = new DataTable();
|
||
|
da.FillSchema(schema, SchemaType.Source);
|
||
|
Assert.AreEqual(2, schema.Columns.Count);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #27668 FillSchema and Stored Proc with an out parameter
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void GetSchema2()
|
||
|
{
|
||
|
if (Version.Major < 5) return;
|
||
|
|
||
|
execSQL(@"CREATE TABLE Test(id INT AUTO_INCREMENT, PRIMARY KEY (id)) ");
|
||
|
execSQL(@"CREATE PROCEDURE spTest (OUT id INT)
|
||
|
BEGIN INSERT INTO Test VALUES (NULL); SET id=520; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.Add("?id", MySqlDbType.Int32);
|
||
|
cmd.Parameters[0].Direction = ParameterDirection.Output;
|
||
|
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
|
||
|
DataTable dt = new DataTable();
|
||
|
cmd.ExecuteNonQuery();
|
||
|
da.Fill(dt);
|
||
|
da.FillSchema(dt, SchemaType.Mapped);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #26139 MySqlCommand.LastInsertedId doesn't work for stored procedures
|
||
|
/// Currently this is borked on the server so we are marking this as notworking
|
||
|
/// until the server has this fixed.
|
||
|
/// </summary>
|
||
|
/* [Test]
|
||
|
public void LastInsertId()
|
||
|
{
|
||
|
execSQL("CREATE TABLE Test (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(200))");
|
||
|
execSQL("INSERT INTO Test VALUES (NULL, 'Test1')");
|
||
|
execSQL("CREATE PROCEDURE spTest() BEGIN " +
|
||
|
"INSERT INTO Test VALUES (NULL, 'test'); END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.ExecuteNonQuery();
|
||
|
Assert.AreEqual(2, cmd.LastInsertedId);
|
||
|
}
|
||
|
*/
|
||
|
[Test]
|
||
|
public void NoAccessToProcedureBodies()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
string sql = String.Format("CREATE PROCEDURE `{0}`.`spTest`(in1 INT, INOUT inout1 INT, OUT out1 INT ) " +
|
||
|
"BEGIN SET inout1 = inout1+2; SET out1=inout1-3; SELECT in1; END", database0);
|
||
|
execSQL(sql);
|
||
|
|
||
|
string connStr = GetConnectionString(true) + "; use procedure bodies=false";
|
||
|
using (MySqlConnection c = new MySqlConnection(connStr))
|
||
|
{
|
||
|
c.Open();
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", c);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.AddWithValue("?in1", 2);
|
||
|
cmd.Parameters.AddWithValue("?inout1", 4);
|
||
|
cmd.Parameters.Add("?out1", MySqlDbType.Int32);
|
||
|
cmd.Parameters[1].Direction = ParameterDirection.InputOutput;
|
||
|
cmd.Parameters[2].Direction = ParameterDirection.Output;
|
||
|
cmd.ExecuteNonQuery();
|
||
|
|
||
|
Assert.AreEqual(6, cmd.Parameters[1].Value);
|
||
|
Assert.AreEqual(3, cmd.Parameters[2].Value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void BinaryAndVarBinaryParameters()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest(OUT out1 BINARY(20), OUT out2 VARBINARY(20)) " +
|
||
|
"BEGIN SET out1 = 'out1'; SET out2='out2'; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.Add("out1", MySqlDbType.Binary);
|
||
|
cmd.Parameters[0].Direction = ParameterDirection.Output;
|
||
|
cmd.Parameters.Add("out2", MySqlDbType.VarBinary);
|
||
|
cmd.Parameters[1].Direction = ParameterDirection.Output;
|
||
|
cmd.ExecuteNonQuery();
|
||
|
|
||
|
byte[] out1 = (byte[])cmd.Parameters[0].Value;
|
||
|
Assert.AreEqual('o', out1[0]);
|
||
|
Assert.AreEqual('u', out1[1]);
|
||
|
Assert.AreEqual('t', out1[2]);
|
||
|
Assert.AreEqual('1', out1[3]);
|
||
|
|
||
|
out1 = (byte[])cmd.Parameters[1].Value;
|
||
|
Assert.AreEqual('o', out1[0]);
|
||
|
Assert.AreEqual('u', out1[1]);
|
||
|
Assert.AreEqual('t', out1[2]);
|
||
|
Assert.AreEqual('2', out1[3]);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #27093 Exception when using large values in IN UInt64 parameters
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void UsingUInt64AsParam()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL(@"CREATE TABLE Test(f1 bigint(20) unsigned NOT NULL,
|
||
|
PRIMARY KEY(f1)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
|
||
|
|
||
|
execSQL(@"CREATE PROCEDURE spTest(in _val bigint unsigned)
|
||
|
BEGIN insert into Test set f1=_val; END");
|
||
|
|
||
|
DbCommand cmd = new MySqlCommand();
|
||
|
cmd.Connection = conn;
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.CommandText = "spTest";
|
||
|
DbParameter param = cmd.CreateParameter();
|
||
|
param.DbType = DbType.UInt64;
|
||
|
param.Direction = ParameterDirection.Input;
|
||
|
param.ParameterName = "?_val";
|
||
|
ulong bigval = long.MaxValue;
|
||
|
bigval += 1000;
|
||
|
param.Value = bigval;
|
||
|
cmd.Parameters.Add(param);
|
||
|
cmd.ExecuteNonQuery();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #29526 syntax error: "show create procedure" with catalog names containing hyphens
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void CatalogWithHyphens()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// make sure this test is valid
|
||
|
Assert.IsTrue(database0.IndexOf('-') != -1);
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("CREATE PROCEDURE spTest() BEGIN SELECT 1; END", conn);
|
||
|
cmd.ExecuteNonQuery();
|
||
|
|
||
|
cmd.CommandText = "spTest";
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
Assert.AreEqual(1, cmd.ExecuteScalar());
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void ComplexDefinition()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL(@"CREATE PROCEDURE `spTest`() NOT DETERMINISTIC
|
||
|
CONTAINS SQL SQL SECURITY DEFINER COMMENT ''
|
||
|
BEGIN
|
||
|
SELECT 1,2,3;
|
||
|
END");
|
||
|
MySqlCommand command = new MySqlCommand("spTest", conn);
|
||
|
command.CommandType = CommandType.StoredProcedure;
|
||
|
using (MySqlDataReader reader = command.ExecuteReader())
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void AmbiguousColumns()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE TABLE t1 (id INT)");
|
||
|
execSQL("CREATE TABLE t2 (id1 INT, id INT)");
|
||
|
execSQL(@"CREATE PROCEDURE spTest() BEGIN SELECT * FROM t1;
|
||
|
SELECT id FROM t1 JOIN t2 on t1.id=t2.id;
|
||
|
SELECT * FROM t2; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.CommandTimeout = 0;
|
||
|
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
|
||
|
DataSet ds = new DataSet();
|
||
|
try
|
||
|
{
|
||
|
da.Fill(ds);
|
||
|
Assert.Fail("The above should have thrown an exception");
|
||
|
}
|
||
|
catch (Exception)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #31930 Stored procedures with "ambiguous column name" error cause lock-ups
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void CallingFunction()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL(@"CREATE FUNCTION `GetSupplierBalance`(SupplierID_ INTEGER(11))
|
||
|
RETURNS double NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER
|
||
|
COMMENT ''
|
||
|
BEGIN
|
||
|
RETURN 1.0;
|
||
|
END");
|
||
|
|
||
|
MySqlCommand command = new MySqlCommand("GetSupplierBalance", conn);
|
||
|
command.CommandType = CommandType.StoredProcedure;
|
||
|
command.Parameters.Add("?SupplierID_", MySqlDbType.Int32).Value = 1;
|
||
|
command.Parameters.Add("?Balance", MySqlDbType.Double).Direction = ParameterDirection.ReturnValue;
|
||
|
command.ExecuteNonQuery();
|
||
|
double balance = Convert.ToDouble(command.Parameters["?Balance"].Value);
|
||
|
Assert.AreEqual(1.0, balance);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void OutputParametersWithNewParamHandling()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE PROCEDURE spTest(out val1 VARCHAR(350)) " +
|
||
|
"BEGIN SET val1 = '42'; END");
|
||
|
|
||
|
string connStr = GetConnectionString(true);
|
||
|
connStr = connStr.Replace("allow user variables=true", "allow user variables=false");
|
||
|
using (MySqlConnection c = new MySqlConnection(connStr))
|
||
|
{
|
||
|
c.Open();
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", c);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.Add(new MySqlParameter("@val1", MySqlDbType.VarChar)).Direction = ParameterDirection.Output;
|
||
|
int rowsAffected = cmd.ExecuteNonQuery();
|
||
|
|
||
|
Assert.AreEqual(0, rowsAffected);
|
||
|
Assert.AreEqual("42", cmd.Parameters[0].Value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void FunctionWithNewParamHandling()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
// create our procedure
|
||
|
execSQL("CREATE FUNCTION spTest(`value` INT) RETURNS INT " +
|
||
|
"BEGIN RETURN value; END");
|
||
|
|
||
|
string connStr = GetConnectionString(true);
|
||
|
connStr = connStr.Replace("allow user variables=true", "allow user variables=false");
|
||
|
using (MySqlConnection c = new MySqlConnection(connStr))
|
||
|
{
|
||
|
c.Open();
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", c);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
cmd.Parameters.Add(new MySqlParameter("@value", MySqlDbType.Int32)).Value = 22;
|
||
|
cmd.Parameters.Add(new MySqlParameter("@returnvalue", MySqlDbType.Int32)).Direction = ParameterDirection.ReturnValue;
|
||
|
int rowsAffected = cmd.ExecuteNonQuery();
|
||
|
|
||
|
Assert.AreEqual(0, rowsAffected);
|
||
|
Assert.AreEqual(22, cmd.Parameters[1].Value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bug #41034 .net parameter not found in the collection
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public void SPWithSpaceInParameterType()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
|
||
|
execSQL("CREATE PROCEDURE spTest(myparam decimal (8,2)) BEGIN SELECT 1; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.Parameters.Add("@myparam", MySqlDbType.Decimal).Value = 20;
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
object o = cmd.ExecuteScalar();
|
||
|
Assert.AreEqual(1, o);
|
||
|
}
|
||
|
|
||
|
private void ParametersInReverseOrderInternal(bool isOwner)
|
||
|
{
|
||
|
if (Version.Major < 5) return;
|
||
|
|
||
|
execSQL(@"CREATE PROCEDURE spTest(IN p_1 VARCHAR(5), IN p_2 VARCHAR(5))
|
||
|
BEGIN SELECT p_1 AS P1, p_2 AS P2; END");
|
||
|
string spName = "spTest";
|
||
|
|
||
|
string connStr = GetConnectionString(true);
|
||
|
if (!isOwner)
|
||
|
connStr += ";use procedure bodies=false";
|
||
|
using (MySqlConnection c = new MySqlConnection(connStr))
|
||
|
{
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand(spName, c);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
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;
|
||
|
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
|
||
|
DataTable dt = new DataTable();
|
||
|
da.Fill(dt);
|
||
|
string s = GetConnectionString(true);
|
||
|
if (!isOwner)
|
||
|
{
|
||
|
Assert.AreEqual("World", dt.Rows[0][0]);
|
||
|
Assert.AreEqual("Hello", dt.Rows[0][1]);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Assert.AreEqual("Hello", dt.Rows[0]["P1"]);
|
||
|
Assert.AreEqual("World", dt.Rows[0]["P2"]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void ParametersInReverseOrderNotOwner()
|
||
|
{
|
||
|
ParametersInReverseOrderInternal(false);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void ParametersInReverseOrderOwner()
|
||
|
{
|
||
|
ParametersInReverseOrderInternal(true);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void DeriveParameters()
|
||
|
{
|
||
|
if (Version < new Version(5, 0)) return;
|
||
|
if (Version > new Version(6, 0, 6)) return;
|
||
|
|
||
|
execSQL(@"CREATE PROCEDURE spTest (id INT, name VARCHAR(20))
|
||
|
BEGIN SELECT name; END");
|
||
|
|
||
|
MySqlCommand cmd = new MySqlCommand("spTest", conn);
|
||
|
cmd.CommandType = CommandType.StoredProcedure;
|
||
|
MySqlCommandBuilder.DeriveParameters(cmd);
|
||
|
Assert.AreEqual(2, cmd.Parameters.Count);
|
||
|
}
|
||
|
}
|
||
|
}
|