Dapper:过程或函数指定的参数太多

时间:2014-07-31 21:53:20

标签: sql .net sql-server dapper

使用Dapper调用存储过程时,我收到以下错误:

Procedure or function has too many arguments specified

我使用DynamicParameters向查询添加简单参数列表。

参数代码如下所示:

var parameters = new DynamicParameters();
parameters.Add(p.Name, p.Value, direction: p.Mode);

查询代码如下所示:

var result = _connection.Query<T>(
            string.Format("{0}.{1}", request.SchemaName, request.StoredProcedureName),
            parameters,
            commandType: CommandType.StoredProcedure,
            transaction: _transaction);

探查器中执行的sql显示如下:

exec dbo.storedProcedureName @ParameterNames1=N'ParameterName',@ParameterNames2=N'ParameterName',@RemoveUnused=1

@ ParameterNames1根本不是如何调用参数的。实际上,名称是作为值传递的(N&#39; ParameterName&#39;)。 @RemoveUnused参数对我来说似乎是完全随机的,因为它根本不会出现在调用代码中。

可在此处找到完整代码:GitHub project,第61和228行。

编辑:我发现问题是由两次调用相同的过程引起的,结果集不同。所以我第一次用Query调用它,第二次用Query调用它。为什么Dapper在这种情况下遇到麻烦仍然是一个谜。

4 个答案:

答案 0 :(得分:2)

我最近遇到过这个问题,这似乎是由以下原因引起的:

  • 您的存储过程可以返回多个数据集(可能基于a 条件参数)。
  • 您正在使用调用存储过程 Query<T>()代替QueryMultiple(),然后映射数据集 通过Read<T>

我们最近从旧版本的Dapper升级到v1.4以支持表变量参数,我们开始体验此行为是升级的直接结果。

<强>解决方案:

将基于Query<T>的代码转换为QueryMultiple实施。

答案 1 :(得分:1)

我根本无法重现这个:

public void SO25069578_DynamicParams_Procs()
{
    var parameters = new DynamicParameters();
    parameters.Add("foo", "bar");
    try { connection.Execute("drop proc SO25069578"); } catch { }
    connection.Execute("create proc SO25069578 @foo nvarchar(max) as select @foo as [X]");
    var tran = connection.BeginTransaction(); // gist used transaction; behaves the same either way, though
    var row = connection.Query<HazX>("SO25069578", parameters,
        commandType: CommandType.StoredProcedure, transaction: tran).Single();
    tran.Rollback();
    row.X.IsEqualTo("bar");
}
public class HazX
{
    public string X { get; set; }
}

工作正常。 RemoveUnused DynamicParameters属性,位:使用动态参数时,不应添加。我甚至尝试过使用基于模板的构造函数:

parameters = new DynamicParameters(parameters);

但又一次:这很好用。您是否有可能使用真正的,旧的版本的dapper?你用的是哪个版本?

答案 2 :(得分:0)

我意识到这是一个旧线程。但是,我使用的是Nuget软件包的最新版本(1.60.6),最近遇到了此问题。

要重现此内容,您将需要一个存储过程,该存储过程基于输入参数可以返回1或2(大于1)个结果集。在代码中,我也使用2种不同的扩展方法来调用它(QueryMultipleAsync将该参数设置为1或true,QueryAsync将其设置为0或false)。如果您的测试最终调用SP首先返回多个结果集,则随后需要1个结果集的调用将失败,并显示此错误。

我设法解决此问题的唯一方法是将SP分解为2,以便它们具有不同的名称。

作为参考,这是我所说的SP:

var data = await sqlConnection.QueryAsync<T>(
             StoredProcedureName,
             parms,
             transaction: null,
             commandTimeout: null,
             commandType: CommandType.StoredProcedure)

var data = await sqlConnection.QueryMultipleAsync(
                        StoredProcedureName,
                        param: p,
                        commandType: CommandType.StoredProcedure)
                        .Map<Type1, Type2, long>
                        (
                            o1 => o1.Id,
                            o2 => o2.FkId ?? 0,
                            (o1, o2) => { o1.Children = o2.ToList(); }
                        );

答案 3 :(得分:0)

最近遇到了这个问题,因为使用不同的 Dapper 方法两次调用相同的过程。
第一次调用相同的 SQL 存储过程是通过 .QueryMultiple。使用 .QuerySingleOrDefault 再次使用参数调用相同的过程导致参数为原始问题中提到的 ParameterNames1 和 RemoveUnused。