求调用存储过程C#的合法示例:MYSQL

Posted

技术标签:

【中文标题】求调用存储过程C#的合法示例:MYSQL【英文标题】:Asking for legitimate example of calling stored procedure C#: MYSQL 【发布时间】:2016-12-06 21:28:29 【问题描述】:

我花了大约 7 个小时试图通过反复试验来解决这个问题。我看到的所有在线示例要么不起作用,要么不适用,或者只显示了我正在寻找的一半。

这是我的要求: 1. mysql中使用一个IN参数和一个OUT参数的简单存储过程示例。 2. 使用 C# 从 Visual Studio 调用 FUNCTIONING 的示例(非常重要,因为有时在线示例无法正常工作...)。文本调用或存储过程命令类型都可以工作。 3. AddWithValue 已被弃用。 4. 我希望看到 out 参数真正起作用。

如果这对于 MYSQL 和 Visual Studio 是不可能的,那也很高兴知道。

MYSQL 文档对于这个特定示例来说不够详尽。并且请不要仇恨 Visual Studio 或 C#。

提前致谢! :)

编辑:

这是我到目前为止所做的,但它不起作用!!!

MYSQL 端,使用 HeidiSQL:

CREATE DEFINER=`root`@`localhost` PROCEDURE `login`(IN `stuff` VARCHAR(50), IN `pass` VARCHAR(50), OUT `param3` INT)
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

    set param3 = 0;
    set param3 = (select count(*) from users where username=stuff and userpassword=pass);
    select @param3;

END

在 C# 方面,我尝试获取此 OUT 参数。现在,这是在多次迭代之后,我已经破坏了函数曾经是什么,并将其归结为两个问题:1. OUT 参数不起作用,以及 2. 即使 Visual Studio 传递 IN 参数,SQL 拒绝认识他们。

protected void Login_Authenticate(object sender, AuthenticateEventArgs e)
    
        using (MySqlConnection con = new MySqlConnection(strcon))
        
            con.Open();

            MySqlCommand com = new MySqlCommand("CALL login(@stuff, @pass, @param3);", con);
            com.CommandType = CommandType.Text;
            com.Parameters.Add("@stuff", MySqlDbType.VarChar);
            com.Parameters["@stuff"].Value = Login.UserName;
            com.Parameters.Add("@pass", MySqlDbType.VarChar);
            com.Parameters["@pass"].Value = Login.Password;

            try
            
                obj = com.ExecuteScalar();
                objparam = com.Parameters["param3"].Value;
                if (Convert.ToInt32(obj) != 0)
                
                    Response.Redirect("Welcome.aspx");
                
                else
                
                    Login.PasswordRequiredErrorMessage = "invalid user name and password";
                
            
            catch (Exception ex)
            
                Console.WriteLine(ex.Message);
            

            con.Close();
        
    

【问题讨论】:

当您的 Q 即将结束时,请使用 edit 重新开始。显示你想出的最接近的 我进行了编辑,以显示我当前的迭代是什么不起作用。这是我想出的最接近的。 感谢您展示您的尝试。这个特定的问题很难作为一个解决方案放在一起。请注意,MySQL .NET 连接器最近添加了处理OUT 参数的功能。多久以前,我不知道。所以,我目前正在使用最新的连接器version 6.9.9.0 哦...这解释了为什么示例和文档不存在。耶出血边缘!大声笑 我有一个文档参考:5.10.1 Using Stored Routines from Connector/Net 【参考方案1】:

我相信代码和图片比以往任何时候都更能说明问题。

C# DB 层(DB 层有conn 作为连接字符串):

// Note: this is an instance (myDB in terms of the GUI Object)

using System.Data;
using MySql.Data.MySqlClient;
...
...
public long MultBySeven(long theNum)
   // Call a Mysql Stored Proc named "multBy7"
    // which takes an IN parameter, Out parameter (the names are important. Match them)
    // Multiply the IN by 7 and return the product thru the OUT parameter

    long lParam = 0;
    using (MySqlConnection lconn = new MySqlConnection(connString))
    
        lconn.Open();
        using (MySqlCommand cmd = new MySqlCommand())
        
            cmd.Connection = lconn;
            cmd.CommandText = "multBy7"; // The name of the Stored Proc
            cmd.CommandType = CommandType.StoredProcedure; // It is a Stored Proc

            // Two parameters below. An IN and an OUT (myNum and theProduct, respectively)
            cmd.Parameters.AddWithValue("@myNum", theNum); // lazy, not specifying ParameterDirection.Input;
            cmd.Parameters.AddWithValue("@theProduct", MySqlDbType.Int32);
            cmd.Parameters["@theProduct"].Direction = ParameterDirection.Output; // from System.Data
            cmd.ExecuteNonQuery(); // let it rip
            Object obj = cmd.Parameters["@theProduct"].Value;
            lParam = (Int32)obj;    // more useful datatype
        
    
    return (lParam);

C# GUI 测试层:

private void btnTestInOut_Click(object sender, EventArgs e)
   // This GUI Layer call thru the use of a business object or data layer object (`myDB`)
    long localHere = myDB.MultBySeven(11);

存储过程(取一个数,乘以 7):

DROP PROCEDURE IF EXISTS multBy7;
DELIMITER $
CREATE PROCEDURE multBy7
(   IN myNum INT,
    OUT theProduct INT
)
BEGIN
    SET theProduct=myNum*7;
END$
DELIMITER ;

调试视图(阅读:它可以工作。11x7=77):

MySQL Connector 6.9.9.0 / Visual Studio 2015

另见5.10.1 Using Stored Routines from Connector/Net,年龄不详。

【讨论】:

感谢您,我意识到我没有安装所有必需的软件包。除了修复代码之外,我还必须 NuGet mysql Web、实体框架和连接器。我以为我以前做过,但显然不是。【参考方案2】:

你应该设置对参数的引用

var param3 = new MySqlParameter();
param3.Direction = ParameterDirection.Output;
param3.DbType = // whatever the dbtype for int is or whatever you need.
param3.ParameterName = "param3";

com.Parameters.Add(param3);

在你的 try 块中,插入

var result = com.ExecuteReader(); // or com.ExecuteScalar();

执行该操作后,您的参数应该填充了值,并且您还应该能够读取 SP 结果(选择)。

var paramResult = param3.Value;

读取 SP 的结果可以作为 reader 或 scalar。

// execute reader
while (result.Read()) 
    int value = result.GetInt32(0)); 
 /* read returned values in result */ 

// execute scalar
int value;
if (int.TryParse($"result", out value)) 
    /* do something with value */ 

/**************************************************** **/

这个块应该可以带你去你需要去的地方

        const string strcon = "whatevs";

        using (MySqlConnection con = new MySqlConnection(strcon))
        
            const string sql = "login";

            MySqlCommand com = new MySqlCommand(sql, con);
            com.CommandType = CommandType.StoredProcedure;

            var stuffParam = new MySqlParameter("stuff", stuffValue);
            var passParam = new MySqlParameter("pass", passValue);
            var param3Param = new MySqlParameter();
            param3Param.ParameterName = "param3";
            param3Param.DbType = DbType.Int32;
            param3Param.Direction = ParameterDirection.Output;

            com.Parameters.Add(stuffParam);
            com.Parameters.Add(passParam);
            com.Parameters.Add(param3Param);

            try
            
                var scalarResult = com.ExecuteScalar();

                // because you used select @param3 in your sp.
                int value;
                if (int.TryParse($"scalarResult", out value))
                
                    //do something with value
                

                //// because you used select @param3 in your sp.
                //var readerResult = com.ExecuteReader();

                //if (readerResult.Read())
                //
                //    // 
                //    value = readerResult.GetInt32(0);
                //

                int param3Returned;
                if(int.TryParse($"param3Param.Value", out param3Returned))
                
                    // do something with param3Returned
                
            
            catch (Exception ex)
            
                // do something with ex
            
        

【讨论】:

这看起来非常接近可能会起作用的方法。我现在正在破解我的代码。谢谢! scalarResult 是什么属性? Intellisense 说它不存在。 哦,忽略最后一个关于标量结果的问题。 我想我现在已经非常接近答案了。我使用了您的代码和所有内容,但现在它给了我一个新错误。这就是说,执行期间出现异常:'login'参数'stuff'未定义。只要我执行Scalar 或executeReader。 我已经更新了参数定义的代码——不需要@符号。对不起。 非常感谢!我花了很多时间试图弄清楚这一点!删除@就可以了。

以上是关于求调用存储过程C#的合法示例:MYSQL的主要内容,如果未能解决你的问题,请参考以下文章

C# 如何调用此存储过程

mysql 存储过程提示错误!!求高人解答

mysql存储过程 把SQL语句返回结果赋给一个变量,该SQL语句返回的结果不止一条,该怎么写,新手,求指教!

myBatis 调用 Oracle 存储过程,报错,求解答

c# 调用Oracle存储过程 PLS-00201:必须声明标识符

mysql中存储过程和游标调用问题