0

可能重复:
SQL Server 和 .net 支持使用参数值调用存储过程而不提供参数名称?

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

4 回答 4

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 时选择参数名称和值。

于 2012-09-12T10:26:09.607 回答
1

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

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

但是,如果您只想不关心名称并自动发现它 - 那么您可以使用Conrad Frix在他接受的关于SQL Server 和 .net 支持调用具有参数值的存储过程而不提供参数名称的答案中提到的技术?- 这就是为什么我标记为重复,因为它最终是你想要做的,即使原因不同。

于 2012-09-12T09:55:41.377 回答
1

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

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

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

于 2012-09-12T09:55:46.900 回答
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();
            }
    }
}
于 2012-09-12T10:09:24.293 回答