2012-09-12 37 views
0

可能重复:
SQL Server & .net support calling a stored procedure with param's values wihout providing param's names?C#SQL执行存储procudere不管传递的参数名称

我想打电话给一个Command.ExecuteReader却()存储过程型的,但我不希望我传递的参数名称与SP中的相同。下面是什么,我试图做一个样品

SP:

ALTER PROCEDURE SPName 
@Id nvarchar(50) 
AS 
BEGIN 
    SET NOCOUNT ON; 
SELECT * FROM TableName 
WHERE ColumnName = @Id 
END 
GO 

代码:

using (SqlCommand command = new SqlCommand(spName, connection) { CommandType = CommandType.StoredProcedure }) 
{ 
    command.parameters.Add(new SqlParameter(*paramaeter name*, sqlDbType.nvarchar){ Value = "SomeValue"}; 
} 
+0

所以你不想传递参数或者你不知道参数名称? –

+3

如果我理解正确,你想调用一个参数叫做@somethingelse的参数调用@Id说的sp。我不认为这是可能的,但我也在努力理解你为什么想要 - 你想解决什么问题? –

+0

我想写一个通用的方法,其中我传递参数对象[],并通过它们循环填充参数集合传递给SP。我的观点是我不想被迫通过param的名字。 – ancdev

回答

1

简单的事实 - 你最终不得不调用存储时,使用正确的参数名过程,因为SQL服务器通过名称绑定参数(即使您使用EXEC调用SP而不使用命名参数,解析器将按名称从左到右进行绑定)。

所以如果你想使用不同的名字,你需要在你的SqlCommand和目标SP之间引入一个中间层。

但如果你只是想不关心名字,并让它自动发现 - 那么你可以使用Conrad Frix提到的技术在他接受的答案上SQL Server & .net support calling a stored procedure with param's values wihout providing param's names? - 这就是为什么我已经标记为重复,因为它最终是你想做什么,即使原因不同。

1

对于SqlServer,有一个DeriveParameters方法,它接受一个命令对象并向数据库查询请求的存储过程的参数(名称和类型)。

然后,您可以遍历它们并提供值。

注意:这意味着额外的旅行到数据库,所以如果你经常需要这个,你可能想缓存结果。

0

下面的方法可以让你编写通用的代码调用存储过程,也使您能够为每个不同的存储过程

public delegate void SqlCOmmandDelegate(SqlCommand command); 

public class Dal 
{ 
    public void ExecuteStoredProcedure(string procedureName, 
     SqlCommandDelgate commandDelegate) 
    { 
     using (SqlConnection connection = new SqlConnection()) 
     { 
      connection.ConnectionString = GetConnectionString(); 
      using (SqlCommand command = connection.CreateCommand()) 
      { 
       command.CommandType = CommandType.StoredProcedure; 
       command.CommandText = procedureName; 
       connection.Open(); 
       commandDelegate(command); 
      } 
     } 
    } 
} 

class UsesDal 
{ 
    public CallFirstProcedure(int value) 
    { 
     string userName; 

     ExecuteStoredProcedure("FIRST_PROCEDURE", 
      delegate(SqlCommand command) 
      { 
       command.Parameters.Add("UserID", value); 
       command.ExecuteReader(); 

       //Do stuff with results e.g. 
       username = command.Parameters.Parameters["UserName"].ToString(); 
      } 
    } 

    public CallOtherProcedure(string value) 
    { 
     int id; 
     ExecuteStoredProcedure("OTHER_PROCEDURE", 
      delegate(SqlCommand command) 
      { 
       command.Parameters.Add("ParameterName", value); 
       id = command.ExecuteScalar(); 
      } 
    } 
} 
2

执行特定的操作。如果你想有一个通用的样式功能,而不需要灵活性一个额外的往返旅行,你很高兴使用反射,你可以使用这样的东西。

// Return an array of SqlParameter's by using reflection on ParamObject 
private static SqlParameter[] GetParametersFromObject(object ParamObject) 
{ 

    var Params = new List<SqlParameter>(); 

    foreach(var PropInfo in ParamObject.GetType().GetProperties()) 
    { 
     Params.Add(new SqlParameter(PropInfo.Name, PropInfo.GetValue(ParamObject, null))); 
    } 

    return Params.ToArray(); 

} 

public static void ExecuteSP(SqlConnection Connection, string SPName, object ParamObject) 
{ 

    using(var Command = new SqlCommand()) 
    { 

     Command.Connection = Connection; 
     Command.CommandType = CommandType.StoredProcedure; 
     Command.CommandText = SPName; 

     Command.Parameters.AddRange(GetParametersFromObject(ParamObject)); 

     // Command.ExecuteReader()... 

    } 

} 

这使用反射从匿名对象中获取属性名称和值来填充SqlCommand。这可以这样使用;

ExecuteSP(Conn, "GetStuff", new { Id = 7, Name = "Test" }); 

这种方式ExecuteSP是'通用',当你调用ExecuteSP时你选择参数名和值。

相关问题