无论传递参数名称如何,C#SQL都会执行存储过程

时间:2012-09-12 09:26:51

标签: c# sql stored-procedures parameters

  

可能重复:
  SQL Server & .net support calling a stored procedure with param's values wihout providing param's names?

我想调用存储过程类型的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"};
}

4 个答案:

答案 0 :(得分: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时选择参数名称和值。

答案 1 :(得分:1)

简单事实 - 您最终必须在调用存储过程时使用正确的参数名称,因为SQL Server按名称绑定参数(即使您使用EXEC调用SP而不使用命名参数,解析器也会从左侧按名称绑定它们)右)。

因此,如果您想使用其他名称,则需要在SqlCommand和目标SP之间引入一个中间层。

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

答案 2 :(得分:1)

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

然后,您可以迭代它们并提供值。

注意:这意味着额外访问数据库,因此如果您经常需要这样做,您可能希望缓存结果。

答案 3 :(得分: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();
            }
    }
}