【问题标题】:C# SQL execute stored procudere regardless of passed parameter name [duplicate]无论传递的参数名称如何,C#SQL都会执行存储的过程[重复]
【发布时间】:2012-09-12 09:26:50
【问题描述】:

可能重复:
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"};
}

【问题讨论】:

  • 所以你不想传递参数或者你不知道参数名称?
  • 如果我理解正确,你想调用一个有参数调用@Id 的sp 说,有一个名为@somethingelse 的参数?我不认为这是可能的,但我也很难理解你为什么想要 - 你想解决什么问题?
  • 我正在尝试编写一个通用方法,在该方法中我传递参数 object[] 并循环遍历它们以填充参数集合以传递给 SP。我的意思是我不想也必须传递参数名称。
  • @ahmadn。我将此问题标记为重复的原因是因为链接到的问题(当然)是相同的,但更重要的是,最佳答案可以满足您的需求。
  • @AndrasZoltan 您提供的链接包含我需要的解决方案。谢谢。

标签: c# sql stored-procedures parameters


【解决方案1】:

如果你想要一个通用的样式函数,不需要额外的往返,并且你很乐意使用反射,你可以使用这样的东西。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        下面的方法允许您编写通用代码来调用存储过程,但也让您可以灵活地为每个不同的存储过程执行特定操作

        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();
                    }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-07
          • 1970-01-01
          • 1970-01-01
          • 2011-07-21
          相关资源
          最近更新 更多