4

I'm trying to call a stored procedure from EF using context.Database.ExecuteSqlCommand since one of my parameters is a datatable.

Here are the procedure's parameters :

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

and here is the c# code calling the stored procedure :

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

As you can see, all parameters are provided, none of them has a null value but I always get this SqlException :

Procedure or function 'UpdateIndicators' expects parameter '@customerId', which was not supplied.

I can't figure out what I am missing. Is the use of SqlParameter wrong ? Parameters are supplied in the same order in the ExecuteSqlCommand even if it is not important.

Thank in advance.

4 Answers 4

7

You are missing the parameters in the SQL string you are executing. Try creating your parameters with an "@" preceding the name and then changing the ExecuteSqlCommand call to:

context.Database.ExecuteSqlCommand("exec MySchema.MyProc @customerId, @indicatorTypeId, @indicators, @startDate, @endDate", customerIdParam, typeIdParam, tableParameter, startDateParam, endDateParam);
Sign up to request clarification or add additional context in comments.

Comments

3

This works:

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

Comments

2

Here is how I currently call my stored procedures with parameters. Replace the parameter names/values with your own. Keep in mind, you may have to list the parameters in the same order as declared in the stored procedure.

Create a SqlParameter array:

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

Then call your stored procedure:

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

Here is the DbHelper code:

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

1 Comment

Slight improvement to allow passing parameters without first declaring a SqlParameter array: public static string GenerateCommandText(string storedProcedure, params SqlParameter[] parameters).
0

Try with this :

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

1 Comment

No, it's not working either, i get the same Exception.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.