Sql server sp_executesql-过程或函数需要未提供的参数
我正在使用C#中的实体框架,并且遇到了一个问题,我已经跟踪到正在生成的SQL语句 存储过程接受表值参数,但这似乎不是问题所在 在SQL Profiler中,我看到正在执行以下操作:Sql server sp_executesql-过程或函数需要未提供的参数,sql-server,tsql,stored-procedures,Sql Server,Tsql,Stored Procedures,我正在使用C#中的实体框架,并且遇到了一个问题,我已经跟踪到正在生成的SQL语句 存储过程接受表值参数,但这似乎不是问题所在 在SQL Profiler中,我看到正在执行以下操作: 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'
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,第16级,状态4,程序保存结果,第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
传递不正确?您正在使用sp\u 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
我已经缩进以使它更清楚。就我所知,第二种变体并不有用。使用第一个。我也有同样的问题 声明命令后,必须指定命令类型
SqlCommand cmd = new SqlCommand(@"sp_name", con);
cmd.CommandType = CommandType.StoredProcedure;
如果不执行此操作,.NET将生成一个用于使用sp_executesql…
的命令,问题是…
您如上所述指定命令类型,生成的代码正在使用
execute storedprocedure @param1 = ...
您必须在sql字符串中指定参数映射才能使其工作。i、 C#代码中的e替换
db.Database.SqlQuery<T>("EXEC dbo.SaveResults", resultId, positiveResults)
db.Database.SqlQuery(“EXEC dbo.SaveResults”、resultId、positiveResults)
与
db.Database.SqlQuery(“EXEC dbo.SaveResults@resultId=@resultId,@positieresults=@positieresults”,resultId,positieresults)
执行存储过程时,
sp_executesql
似乎无法自动将传递的参数与预期参数关联,除非在传递的SQL字符串中手动指定映射。不幸的是,我使用的框架正在使用sp_executesql生成语句。我有手动执行的控制权,但更愿意让它继续生成语句。我试图将EXEC包含到生成的字符串中,但得到的结果相同。。ie exec sp_executesql N'exec dbo.SaveResults…'发布一个可执行的repo(您用SQL事件探查器捕获的内容)。我现在还不清楚问题出在哪里。复制程序与原始post(第一个SQL代码块)中描述的完全一样。这就是通过SQL事件探查器得到的结果。将N'dbo.SaveResults'更改为N'EXEC dbo.SaveResults'会导致相同的“expects parameter@resultID”错误消息。是的,这会导致相同的消息,因为您没有传递参数。注意,我的第二个代码块在EXEC行中传递参数。添加这些。我正在传递它们,它们在滚动区域的右侧。我已经重新设置了原始问题的格式,以便在不滚动的情况下显示完整的查询。这似乎符合你的建议。你是如何执行的?是否无法设置命令类型以使EF知道它是一个存储过程?正在使用DbContext上的Database.ExecuteSqlCommand在EF中执行该命令。它似乎根据来自SQL Server的错误消息(“过程或函数”…预期“参数”)将其识别为存储过程。我正试图确定sp_executesql语法到底出了什么问题,然后根据需要反向修改代码。啊,好的。我想可能有一些命令类型的等价物,这是正确的。!CommandType很神奇,它使SqlCommand生成正确的db语句,您只需要传递sp的名称。我重构并破坏了一些代码,因为我遗漏了CommandType。跌跌撞撞地读了这篇文章之后,我有了一个啊哈!!白痴。撤消。:-)
db.Database.SqlQuery<T>("EXEC dbo.SaveResults @resultId=@resultId, @positiveResults=@positiveResults", resultId, positiveResults)