2014-09-23 53 views
4

我正在使用C#中的實體框架,並且遇到了一個我已經跟蹤到正在生成的SQL語句的問題。sp_executesql - 過程或函數期望不提供的參數

存儲過程需要一個表值參數,但這似乎不是問題。

在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, 
         @[email protected] 

這導致:

消息201,級別16,狀態4,過程SaveResults,行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

你是如何執行這個?有沒有辦法設置命令類型,以便EF知道它是一個存儲過程? – 2014-09-23 20:21:15

+0

它正在EF中使用DbContext上的Database.ExecuteSqlCommand執行。它似乎認識到它是基於來自SQL Server的錯誤消息(「過程或函數」...期望「參數」)的存儲過程。我試圖確定sp_executesql語法究竟出了什麼問題,然後根據需要後退工作以重新編寫代碼。 – Patrick 2014-09-23 20:28:36

+0

啊,好的。我認爲可能有一些類似的命令類型[但似乎並非如此](http://msdn.microsoft.com/en-us/library/system.data.entity.database_methods(v = vs.113 ).aspx) – 2014-09-23 20:34:51

回答

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,@[email protected] 

我已經縮進,使之更加清晰。據我所知,第二個變體沒有用處。使用第一個。

+0

不幸的是,我正在使用的框架是使用sp_executesql生成語句。我有控制手動執行此操作,但寧願讓它繼續生成語句。我試圖將EXEC包含到生成的字符串中,但我得到了相同的結果..即exec sp_executesql N'EXEC dbo.SaveResults ...' – Patrick 2014-09-23 20:10:43

+0

發佈可執行的repro(您使用SQL Profiler捕獲的內容)。我不清楚現在的問題是什麼。 – usr 2014-09-23 20:12:29

+0

repro與原始文章(第一個SQL代碼塊)中所述完全相同。這是通過SQL Profiler傳入的內容。將N'dbo.SaveResults'更改爲N'EXEC dbo.SaveResults'會導致相同的「期望參數@resultID」錯誤消息。 – Patrick 2014-09-23 20:18:02

1

我有同樣的確切問題。

一旦你聲明的命令,你必須指定命令類型

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

cmd.CommandType = CommandType.StoredProcedure; 

如果你不這樣做,.NET可以使用sp_executesql...生成命令,這就是問題...您指定命令類型如上和生成的代碼使用

execute storedprocedure @param1 = ... 
1

你會在你的SQL字符串指定參數映射爲它工作。即,在C#代碼替換

db.Database.SqlQuery<T>("EXEC dbo.SaveResults", resultId, positiveResults) 

看來sp_executesql是無法執行存儲過程時傳遞的參數來自動關聯到期望的參數,除非在SQL被手動指定的映射字符串通過

相關問題