Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sp_executesql - Procedure or function expects parameter which was not supplied

I am working with Entity Framework in C# and am having an issue which I have tracked down to the SQL statement being generated.

The stored procedure takes in a table-valued parameter, but this doesn't seem to be the issue.

In SQL Profiler, I am seeing the following being executed:

declare @p3 dbo.PositiveTypes
insert into @p3 values(N'1')
insert into @p3 values(N'4')
insert into @p3 values(N'6')

    exec sp_executesql N'dbo.SaveResults',
                       N'@resultID int, @positiveResults [PositiveTypes] READONLY',
                         @resultID=1,
                         @positiveResults=@p3

This results in:

Msg 201, Level 16, State 4, Procedure SaveResults, Line 0
Procedure or function 'SaveResults' expects parameter '@resultID', which was not supplied.

The definition of this procedure is:

ALTER PROCEDURE [dbo].[SaveResults] 
    @resultID int, 
    @positiveResults AS dbo.PositiveTypes READONLY

User defined type is:

CREATE TYPE [dbo].[PositiveTypes] AS TABLE(
    [TypeID] [tinyint] NULL
)

What is wrong with this sp_executesql syntax? Why does it think that @resultID is not being passed properly here?

like image 828
Patrick Avatar asked Sep 23 '14 19:09

Patrick


2 Answers

I had the same exact issue.

Once you declare the command, you have to specify the command type

SqlCommand cmd = new SqlCommand(@"sp_name", con);

cmd.CommandType = CommandType.StoredProcedure;

If you don't do this, .NET will generate a command for using sp_executesql... and that is the problem is ... you specify the command type as above and the code generated is using

execute storedprocedure @param1 = ...
like image 131
bobtorres Avatar answered Nov 15 '22 01:11

bobtorres


You're using sp_executesql to run the SQL text dbo.SaveResults. This T-SQL runs the procedure dbo.SaveResults with no parameters. Now you understand where that message comes from. What to do about it? Use EXEC:

EXEC dbo.SaveResults @resultID = 1234, @positiveResults = @p3

Or, nest the call:

exec sp_executesql N'

    EXEC dbo.SaveResults @resultID = @resultID, @positiveResults = @positiveResults

',N'@resultID int, @positiveResults [PositiveTypes] READONLY',@resultID=1,@positiveResults=@p3

I have indented to make it more clear. The 2nd variant is not useful as far as I can tell. Use the first one.

like image 36
usr Avatar answered Nov 14 '22 23:11

usr