【问题标题】:Passing 0-n parameters to SQL Stored Procedure executer method将 0-n 参数传递给 SQL 存储过程执行器方法
【发布时间】:2016-11-15 14:31:13
【问题描述】:

我正在创建一个可以从应用程序中的任何位置调用的方法,该方法将接收存储过程的名称和传递给它的参数列表。

在执行此操作时,我遇到了 Parameters.AddWithValue 命令,但也遇到了博客文章和一些 SO 帖子,这些帖子说由于转换问题,这很糟糕。他们都建议使用

添加参数
Parameters.Add(PARAMETER, SqlDbType.TYPE);

但问题是,如果我有像我这样的方法,当我不知道参数传入时是什么类型时,如何正确使用Parameters.Add 方法?有什么好的方法来解决这个问题,还是我过于偏执而应该坚持使用Parameters.AddWithValue

这里的参考是我现在尝试更新的基本方法,以便它可以处理参数

public static DataTable ExecuteDynamicsStoredProc(string procedureName)
{
    var dataTable = new DataTable();

    using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DynamicsDB"].ToString()))
    {
        using (var command = new SqlCommand("c2s_ProjectPerformanceReport", connection))
        {
            connection.Open();
            command.CommandType = CommandType.StoredProcedure;

            var dataAdapter = new SqlDataAdapter();
            dataAdapter.SelectCommand = command;

            dataAdapter.Fill(dataTable);

            return dataTable;
        }
    }
}

【问题讨论】:

  • 您还应该将参数传递给您的 sp。
  • IMO 你不能同时拥有一个通用方法而不知道调用的 SP 和 类型安全 以避免可能的转换。当然你可以接受一个三元组的数组,比如params Tuple<string, SqlType, object> parameters。不是最好的呼叫点。您也可以添加一个 Action<SqlCommand> 您调用的操作,让调用者有机会以他想要的方式添加参数...
  • 不,拥有这样的方法可能很方便,但它会违反类型安全,除非你将一些责任转移给调用者。当我有这个疑问时,我通常会选择Action<T>(除非您绑定到特定的数据库引擎,在这种情况下,IEnumerable<SqlParameter> 甚至params SqlParameter[] 都非常合适跨度>
  • 或者放弃这种方式,使用轻量级的ORM(例如Dapper)
  • @Steve 但是它具有相同的类型转换问题,因为它不知道底层 SQL 类型 (AFAIK)

标签: c# asp.net sql-server


【解决方案1】:

您可以使该方法接受SqlParameter[] 并使用command.Parameters.AddRange()

public static DataTable ExecuteDynamicsStoredProc(string procedureName, SqlParameter[] args) {
    var dataTable = new DataTable();

    using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DynamicsDB"].ToString())) {
        using (var command = new SqlCommand(procedureName, connection)) { //use passed in proc name
            connection.Open();
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.AddRange(args); //add all the parameters
            var dataAdapter = new SqlDataAdapter();
            dataAdapter.SelectCommand = command;
            dataAdapter.Fill(dataTable);
            return dataTable;
        }
    }
}

public static void ExecuteProcOne(string name, int age, bool alive) {            
    SqlParameter p1 = new SqlParameter("name", name);
    SqlParameter p2 = new SqlParameter("age", age);
    SqlParameter p3 = new SqlParameter("alive", alive);

    var result = ExecuteDynamicsStoredProc("ExecuteProcOne", new SqlParameter[] { p1, p2, p3 });
}

使用ExecuteProcOne() 之类的方法来处理具有各自数据类型的各个过程。您可以进一步提取它以使方法返回SqlParameter[]

这样你只需调用MyProcName,你就知道你需要什么来自智能感知的参数。

【讨论】:

  • 感谢您了解 proc 名称。当我测试它时忘记将它恢复为变量。我将深入研究SqlParameter 并尝试看看会发生什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-05
  • 2011-07-21
  • 2015-12-20
相关资源
最近更新 更多