Executing SQL Stored Procedure with Output Parameter from Entity Framework
Asked Answered
C

5

18

Using EF, I'm trying to execute a stored procedure that returns a single string value, i.e. the status of an SQL Agent Job.

The stored procedure is declared as

CREATE PROCEDURE [dbo].[up_GetJobStatus](@JobStatus NVARCHAR(30) OUTPUT)
AS

-- some code omitted for brevity

SELECT @JobStatus = (
SELECT  
    CASE job_state 
    WHEN 1 THEN 'Executing'
    WHEN 2 THEN 'Waiting for thread'
    WHEN 3 THEN 'Between retries'
    WHEN 4 THEN 'Idle'
    WHEN 5 THEN 'Suspended'
    WHEN 6 THEN '<unknown>'
    WHEN 7 THEN 'Performing completion actions'
END
FROM @xp_results results 
INNER JOIN msdb.dbo.sysjobs sj
ON results.job_id = sj.job_id
WHERE sj.job_id = @job_id)

RETURN

I have verified the stored procedure is working correct as I can execute it in query window and it returns

    @JobStatus
  ------------
  1|Idle

However when executing with EF, the param value is NULL

var param = new SqlParameter
{
    ParameterName = "@JobStatus",
    DbType = DbType.String,
    Size = 30,
    Direction = System.Data.ParameterDirection.Output
};

var result = this.etlContext.Database.SqlQuery<string>("EXEC dbo.up_GetJobStatus @JobStatus OUTPUT", param);

I've also tried the ExecuteSqlCommand method but that didn't work either.

Any ideas?

Clarisaclarise answered 27/2, 2014 at 12:5 Comment(4)
Have you tried passing it using: var result = this.etlContext.Database.SqlQuery<string>("EXEC dbo.up_GetJobStatus {0}", param.Value)?;Preserve
tried it - didn't workClarisaclarise
did you get any exceptions? or did it simply return null?Preserve
Have you had a look at this link (msdn.microsoft.com/en-us/library/vstudio/…) on how to do it? you will first need to import the stored procedures into your dbmxPreserve
C
37
  1. Create stored procedure in database

    CREATE PROCEDURE [dbo].myStoredProcName
        @inputParam1 VARCHAR(150),
        @inputParam2 VARCHAR(150),
        @myOutputParamBool BIT OUTPUT,
        @myOutputParamString VARCHAR(100) OUTPUT,
        @myOutputParamInt INT OUTPUT
    AS
    BEGIN
        -- sql here
    END
    
  2. Update entity model from database to include stored procedure as shown here

  1. Call the stored procedure from C# code

    // Type is System.Data.Entity.Core.Objects.ObjectParameter
    ObjectParameter myOutputParamBool = new ObjectParameter("myOutputParamBool", typeof(bool));
    ObjectParameter myOutputParamString = new ObjectParameter("myOutputParamString", typeof(string));
    ObjectParameter myOutputParamInt = new ObjectParameter("myOutputParamInt", typeof(Int32));
    
    using (var context = new SandCryptEntities())
    {
        context.myStoredProcName(inputParam1, inputParam2, myOutputParamBool, myOutputParamString, myOutputParamInt);   
    }
    
    bool myBool = Convert.ToBoolean(myOutputParamBool.Value);
    string myString = Convert.ToString(myOutputParamString.Value);
    int myInt = Convert.ToInt32(myOutputParamInt.Value);
    
Cupid answered 5/1, 2017 at 15:12 Comment(1)
I do have Table Types as my params to SP, so They didn't come as param in sp if I follow your way, please suggestClaribelclarice
L
4

Here's an actual answer. Apparently there are serious issues with output parameters in entity framework when you're using DbContext/code first. This article has a good discussion and workaround: http://weblogs.asp.net/dwahlin/using-entity-framework-code-first-with-stored-procedures-that-have-output-parameters. Apparently it's supposed to be "fixed" with an update, but I haven't really seen that happen.

Lincoln answered 18/9, 2014 at 21:14 Comment(0)
B
3

Use the following code. It is working for me.

var param = new SqlParameter
{
    ParameterName = "@JobStatus",
    DbType = DbType.String,
    Size = 30,
    Direction = System.Data.ParameterDirection.Output
};

var result = this.etlContext.Database.SqlQuery<string>("EXEC dbo.up_GetJobStatus @JobStatus=@JobStatus OUTPUT", param);
string JobStatus = param.Value.ToString();

The first @JobStatus is your param ParameterName and the second @JobStatus is the PROCEDURE Parameter name.

Bk answered 29/2, 2020 at 11:6 Comment(0)
G
2

Just to build on vicky's answer.

var localPar = new SqlParameter("@userlogin", ad);
var Paramater2 = new SqlParameter("@Paramater2", "");
Paramater2.Direction = ParameterDirection.Output;
Paramater2.Size = 30;
Paramater2.DbType = DbType.String;

var parameters = new List<SqlParameter>();
parameters.Add(localPar);
parameters.Add(Paramater2);


var result = this.Database.SqlQuery<object>("EXEC dbo.uspSP @userlogin, @Paramater2 =@Paramater2 OUTPUT", parameters.ToArray());

var x = result.FirstOrDefault();

return Paramater2.Value.ToString();

If you have more than 1 parameter.

Gelation answered 24/4, 2020 at 9:46 Comment(0)
B
1

Just need a slight change.

First Building Your Query-

var query=@"$Declare @return_Value nvarchar(30) @JobStatus nvarchar(30)
EXEC @return_Value=up_GetJobStatus @JobStatus=@JobStatus
SELECT @JobStatus as N'@JobStatus'";

Secondly, using SqlQueryRaw.

var result = this.etlContext.Database.SqlQueryRaw<string> 
("query").AsEnumerable().FirstOrDefault();

result should have the value you are looking for.

Bulger answered 19/7, 2023 at 13:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.