我正在使用C#中的Entity Framework,我遇到了一个问题,我已经跟踪了生成的SQL语句。
存储过程采用表值参数,但这似乎不是问题。
在SQL事件探查器中,我看到以下内容正在执行:
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
这导致:
Msg 201,Level 16,State 4,Procedure SaveResults,Line 0
程序或功能' SaveResults'期望参数' @ resultID',这是未提供的。
此程序的定义是:
ALTER PROCEDURE [dbo].[SaveResults]
@resultID int,
@positiveResults AS dbo.PositiveTypes READONLY
用户定义的类型是:
CREATE TYPE [dbo].[PositiveTypes] AS TABLE(
[TypeID] [tinyint] NULL
)
这个sp_executesql
语法有什么问题?为什么认为@resultID
没有在这里正确传递?
答案 0 :(得分:4)
您正在使用sp_executesql
来运行SQL文本dbo.SaveResults
。此T-SQL运行没有参数的过程dbo.SaveResults
。现在您了解该消息的来源。该怎么办?使用EXEC
:
EXEC dbo.SaveResults @resultID = 1234, @positiveResults = @p3
或者,嵌套电话:
exec sp_executesql N'
EXEC dbo.SaveResults @resultID = @resultID, @positiveResults = @positiveResults
',N'@resultID int, @positiveResults [PositiveTypes] READONLY',@resultID=1,@positiveResults=@p3
我已经缩进以使其更清晰。就我所知,第二个变体没用。使用第一个。
答案 1 :(得分:3)
我有同样的问题。
声明命令后,必须指定命令类型
SqlCommand cmd = new SqlCommand(@"sp_name", con);
cmd.CommandType = CommandType.StoredProcedure;
如果你不这样做,.NET将生成一个使用sp_executesql...
的命令,问题是...
你指定了上面的命令类型,生成的代码正在使用
execute storedprocedure @param1 = ...
答案 2 :(得分:1)
您必须在sql字符串中指定参数映射才能使其正常工作。即在C#代码中替换
db.Database.SqlQuery<T>("EXEC dbo.SaveResults", resultId, positiveResults)
与
db.Database.SqlQuery<T>("EXEC dbo.SaveResults @resultId=@resultId, @positiveResults=@positiveResults", resultId, positiveResults)
在执行存储过程时,似乎sp_executesql
无法自动将传递的参数与预期参数关联,除非在传递的SQL字符串中手动指定了映射