使用ExecuteSqlCommand调用存储过程(需要未提供的参数)

本文关键字:参数 调用 ExecuteSqlCommand 存储过程 使用 | 更新日期: 2023-09-27 18:24:12

我正试图使用context.Database.ExecuteSqlCommand从EF调用存储过程,因为我的一个参数是数据表。

以下是程序的参数:

ALTER PROCEDURE [mySchema].[myProc]
    @customerId INT,
    @indicatorTypeId INT,
    @indicators [mySchema].[IndicatorList] READONLY,
    @startDate DATETIME,
    @endDate DATETIME

这是调用存储过程的c#代码:

var indicatorsDt = new DataTable();
indicatorsDt.Columns.Add("Date", typeof(DateTime));
indicatorsDt.Columns.Add("Ongoing", typeof(int));
indicatorsDt.Columns.Add("Success", typeof(int));
indicatorsDt.Columns.Add("Warning", typeof(int));
indicatorsDt.Columns.Add("Error", typeof(int));
indicatorsDt.Columns.Add("Other", typeof(int));
var customerIdParam = new SqlParameter("customerId", SqlDbType.Int);
customerIdParam.Value = customerId;
var typeIdParam = new SqlParameter("indicatorTypeId", SqlDbType.Int);
typeIdParam.Value = typeId;
var startDateParam = new SqlParameter("startDate", SqlDbType.DateTime);
startDateParam.Value = startDate;
var endDateParam = new SqlParameter("endDate", SqlDbType.DateTime);
endDateParam.Value = endDate;
foreach (var indicator in indicators)
{
    indicatorsDt.Rows.Add(indicator.Date, indicator.Ongoing, 
                          indicator.Success, indicator.Warning, 
                          indicator.Error, indicator.Other);
}
var tableParameter = new SqlParameter("indicators", SqlDbType.Structured);
tableParameter.Value = indicatorsDt;
tableParameter.TypeName = "MySchema.IndicatorList";
context.Database.ExecuteSqlCommand("exec MySchema.MyProc", customerIdParam, typeIdParam, tableParameter, startDateParam, endDateParam);

正如你所看到的,所有的参数都被提供了,没有一个参数有空值,但我总是得到这个SqlException:

过程或函数"UpdateIndicators"需要参数"@customerId",但未提供。

我想不出我缺了什么。SqlParameter的使用是否错误?参数在ExecuteSqlCommand中以相同的顺序提供,即使它不重要。

提前感谢。

使用ExecuteSqlCommand调用存储过程(需要未提供的参数)

您正在执行的SQL字符串中缺少参数。尝试在名称前添加"@"创建参数,然后将ExecuteSqlCommand调用更改为:

context.Database.ExecuteSqlCommand("exec MySchema.MyProc @customerId, @indicatorTypeId, @indicators, @startDate, @endDate", customerIdParam, typeIdParam, tableParameter, startDateParam, endDateParam);

以下是我当前如何使用参数调用存储过程。将参数名称/值替换为您自己的名称/值。请记住,您可能必须按照存储过程中声明的顺序列出参数。

创建SqlParameter数组:

SqlParameter[] parameters = new SqlParameter[] {
     new SqlParameter("@ParamName1", Value1),
     new SqlParameter("@ParamName2", Value2),
     new SqlParameter("@ParamName3", Value3),
     new SqlParameter("@ParamName4", Value4),
     new SqlParameter("@ParamName5", Value5)
};

然后调用您的存储过程:

 _context.Database.ExecuteSqlCommand(DbHelper.GenerateCommandText("SpName", parameters), parameters);

这是DbHelper代码:

public class DbHelper
{
    public static string GenerateCommandText(string storedProcedure, SqlParameter[] parameters)
    {
        string CommandText = "EXEC {0} {1}";
        string[] ParameterNames = new string[parameters.Length];
        for (int i = 0; i < parameters.Length; i++)
        {
            ParameterNames[i] = parameters[i].ParameterName;
        }
        return string.Format(CommandText, storedProcedure, string.Join(",", ParameterNames));
    }
}

这是有效的:

var bookIdParameter = new SqlParameter();
bookIdParameter.ParameterName = "@BookId";
bookIdParameter.Direction = ParameterDirection.Output;
bookIdParameter.SqlDbType = SqlDbType.Int;
var authors = context.Database.ExecuteSqlCommand("usp_CreateBook @BookName, @ISBN, @BookId OUT",
    new SqlParameter("@BookName", "Book"),
    new SqlParameter("@ISBN", "ISBN"),
    bookIdParameter);

试试这个:

var customerIdParam = new SqlParameter("@customerId", SqlDbType.Int);