【问题标题】:Call stored procedure in C#在 C# 中调用存储过程
【发布时间】:2012-05-20 08:16:53
【问题描述】:

我想使用 C# 调用存储过程。

我想为过程调用创建一个简写。

我仍然不想重新定义连接并打开它。 如何创建方法 - 我仍然没有打开与数据库的连接?

我使用以下代码:

SqlConnection conn = null;
SqlDataReader rdr  = null;

conn = new SqlConnection("");
conn.Open();

SqlCommand cmd  = new SqlCommand("Procedure", conn);
cmd.CommandType = CommandType.StoredProcedure;

rdr = cmd.ExecuteReader();

while (rdr.Read())
{
}

【问题讨论】:

  • 哎哟。我认为您需要澄清或重新考虑您的问题。如果您问我们如何将其包装在一个方法中,您需要的帮助比我们所能提供的更多。此外,您还缺少使用和/或 Dispose() 调用的垃圾负载。
  • 我还是不想重新定义连接并打开它。你能改一下吗?我不明白。
  • 首先您阅读有关 SqlConnection 的 MSDN 文档,它将回答您的一半问题。

标签: c# stored-procedures


【解决方案1】:

我不知道我是否理解你在问什么,但你的意思是这样的:

public static SqlReader executeProcedure(SqlConnection oConn, string commandName, Dictionary<string, object> params)
{
    SqlCommand comm = oConn.CreateCommand();
    comm.CommandType = CommandType.StoredProcedure;
    comm.CommandText = commandName;
    if (params != null)
        foreach(KeyValuePair<string, object> kvp in params)
            comm.Parameters.Add(new SqlParameter(kvp.Key, kvp.Value));
    return comm.ExecuteReader();
}

一个使用示例可能是

Dictionary<string, object> paras = new Dictionary<string, object>();
paras.Add("user_name", "Timmy");
paras.Add("date", DateTime.Now);
SqlReader results = executeProcedure(oConn, "sp_add_user", paras);
while (results.Read())
{
    //do something with the rows returned
}
results.Close();

【讨论】:

  • 如何创建检索数据的方法?我需要读取数据。
  • 您不能真正创建一种方法来检索数据,因为列会随您调用的任何存储过程而变化。您可以只增加SqlReader 中的行并处理直到完成。
  • 我已经更新了我的答案,但你真的应该在这里查看SqlCommand 的文档:msdn.microsoft.com/en-us/library/…
  • 谢谢 FlyingStreudel!你能举个例子:我如何定义参数(在输入中)?
  • 在方法内部打开SqlConnection并像这样执行阅读器会更安全:return comm.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
【解决方案2】:

FlyingStreudel 的回答很好,但我已经修改了该代码以制作演示最佳实践的版本(底部的链接)。您还可以使用 Microsoft 的 Enterprise Library,它将为您提供强大的数据访问类。

private string _connectionString = "yourconnectionstring"; // from web.config, or wherever you store it
public static SqlDataReader executeProcedure(string commandName, 
                                         Dictionary<string, object> params)
{
    SqlConnection conn = new SqlConnection(_connectionString);
    conn.Open();
    SqlCommand comm = conn.CreateCommand();
    comm.CommandType = CommandType.StoredProcedure;
    comm.CommandText = commandName;
    if (params != null)
    {
        foreach(KeyValuePair<string, object> kvp in params)
            comm.Parameters.Add(new SqlParameter(kvp.Key, kvp.Value));
    }
    return comm.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
}

用过,像这样:

Dictionary<string, object> paras = new Dictionary<string, object>();
paras.Add("user_name", "Timmy");
paras.Add("date", DateTime.Now);
using(SqlDataReader results = executeProcedure("sp_add_user", paras))
{
    while (results.Read())
    {
        //do something with the rows returned
    }
}

参考资料:

How Microsoft use Connections in Enterprise Library

Keeping an SqlConnection open is 'foo bar'

Returning a data reader from a class

【讨论】:

  • 您合法地只是复制并粘贴了我的代码并添加了两行。为每个过程调用创建连接并不是“最佳实践”。您拥有私有连接字符串变量的方法也很糟糕,如果您想更改正在使用的数据库,现在必须重新编译您的代码。
  • 感谢您的反馈。您可以根据自己的喜好分配连接字符串(来自配置是正常的,因此我为此添加了注释)。是的,正确关闭连接只需要一两行代码,但这很重要。
【解决方案3】:
using (SqlConnection sqlConnection1 = new SqlConnection("Your Connection String")) {
using (SqlCommand cmd = new SqlCommand()) {
  Int32 rowsAffected;

  cmd.CommandText = "StoredProcedureName";
  cmd.CommandType = CommandType.StoredProcedure;
  cmd.Connection = sqlConnection1;

  sqlConnection1.Open();

  rowsAffected = cmd.ExecuteNonQuery();

}}

【讨论】:

    【解决方案4】:

    如果您希望重用此类代码,一种可能的解决方案是将此类方法(执行存储过程并返回结果的方法)包装到应用程序的通用数据访问层中。您必须考虑的变化是针对不返回结果或期望参数的过程。

    例如,您可以将此 shell 代码包装为 ExecuteProcedure(),它需要返回数据库的连接字符串。

    还有无数其他方法可以完成此类任务,因此您需要确定最适合您的特定要求的选项。

    【讨论】:

      【解决方案5】:

      您可以包装此代码并将过程作为参数。像这样的:

      public SqlCommand GetData(string procedure)
      {
        var conn = new SqlConnection(connectionString);
        var cmd = new SqlCommand(procedure, conn);
      
        cmd.CommandType = CommandType.StoredProcedure;
        conn.Open();
        return cmd;
      }
      

      这种方法的唯一问题是你没有正确地处理资源并且依赖于调用者这样做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多