2014-10-28 42 views
2

我只是想知道是否有办法执行存储过程而无需命名参数。这意味着C#按照在存储过程中声明的顺序解析参数。使用无名参数执行存储过程

public static DataTable GetRelatedResources(string StoredProcedure, object[] Parameters) 
{ 
    var Results = new DataTable(); 

    try 
    { 
     using (SqlConnection conn = new SqlConnection()) 
     { 
      using (SqlCommand cmd = new SqlCommand(ConfigurationManager.ConnectionStrings["MK3Entities"].ConnectionString)) 
      { 
       conn.Open(); 
       cmd.Connection = conn; 
       cmd.CommandType = CommandType.StoredProcedure; 
       cmd.CommandText = StoredProcedure; 

       if (Parameters!= null) 
       { 
        foreach(var Param in Parameters) 
        { 
         // I Want To Do something like this 
         cmd.Parameters.AddWithValue(Param); 
        } 
       } 

       SqlDataAdapter adapter = new SqlDataAdapter(cmd); 
       adapter.Fill(Results); 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     MMSLogger.Instance.WriteToLog("Exception Executing Stored Procedure:" + ex.Message); 
    } 

    return Results; 
} 
+0

否;但你可以调用'DeriveParameters'来动态加载所需的参数(或者手动创建一个'EXEC'字符串) – 2014-10-28 14:48:51

+2

你的问题听起来像是有什么方法可以在我的脚上拍摄吗?为什么?将参数传递给存储过程时,您知道要传递哪个参数的数据,为什么不把名称与它一起发送? – 2014-10-28 14:52:04

+0

序数参数传递通常不是可取的,并且可能导致很多[像这样的问题](http://stackoverflow.com/a/26547211/314291)。如果你真的必须这样做,那么你可以使用[OleDb](http://stackoverflow.com/q/2407685/314291)而不是'SqlClient' – StuartLC 2014-10-28 14:53:14

回答

3

执行一个命令代替,并传入参数 '@ P1', '@ P2' 等等:

cmd.CommandType = CommandType.Text; 
cmd.CommandText = 'exec ' + StoredProcedure; 

int i=0; 
string comma = ' '; 
foreach(var Param in Parameters) 
    { 
    var paramName = String.Format("@P{0}", i); 
    cmd.CommandText += comma + paramName; 
    cmd.Parameters.AddWithValue(paramName, Param); 
    ++i; 
    comma = ', '; 
    } 

注意AddwithValue是巨大的性能反模式。见How Data Access Code Affects Database Performance

+0

在这种情况下SQL注入是什么? – BendEg 2014-10-28 15:03:54

+2

@BendEg:什么是?仍然是参数化执行,并且没有SQL是从用户输入构建的。 – 2014-10-28 15:08:26

+1

这一切都完美谢谢 – 2014-10-28 17:51:21

3

作为每MSDN

的参数名称在形式@paramname指定。您需要必须设置 ParameterName在执行依赖于参数的SqlCommand之前。

Another MSDN文章SqlCommand

无名,也称为序,参数不被 .NET Framework数据提供了SQL Server支持

因此答案是否定的,没有命名参数就无法执行存储过程。

3

你的意思是有点像导出的参数。这MSDN article给了概览:

参数也可以从使用 DbCommandBuilder将类存储过程的。 SqlCommandBuilder和OleDbCommandBuilder类都提供了一种静态方法DeriveParameters,它可以自动填充使用存储过程中的参数信息的命令 对象的参数集合。注意 DeriveParameters覆盖该命令的任何现有参数信息 。

另一个解决办法是从sql数据库中获取存储过程的参数并将它们设置在您的代码中。但是这需要一个额外的查询。要获取参数使用:

select * from dbo.parameters where specific_name='procedure-name' 

但无论如何,您必须使用参数名称。