2014-09-23 3 views
4

Я работаю с Entity Framework в C#, и у меня есть проблема, которую я отследил до сгенерированного оператора SQL.sp_executesql - Процедура или функция ожидает параметр, который не был отправлен

Хранимая процедура принимает параметр таблицы, но это, похоже, не является проблемой.

В 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', 
         N'@resultID int, @positiveResults [PositiveTypes] READONLY', 
         @resultID=1, 
         @[email protected] 

Это приводит к:

Msg 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 знал, что это хранимая процедура? –

+0

Он выполняется в EF, используя Database.ExecuteSqlCommand в DbContext. Кажется, он распознает его как хранимую процедуру на основе сообщения об ошибке с SQL Server («процедура или функция» ... ожидает «параметр»). Я пытаюсь точно определить, что не так с синтаксисом sp_executesql, а затем работать обратно, чтобы переработать код по мере необходимости. – Patrick

+0

А, ОК. Я думал, что может быть некоторый эквивалент типа команды [но, похоже, не так) (http://msdn.microsoft.com/en-us/library/system.data.entity.database_methods (v = vs.113) .aspx) –

ответ

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] 

Я отступом, чтобы сделать его более ясным. Насколько я могу судить по 2-му варианту. Используйте первый.

+0

К сожалению, фреймворк, который я использую, генерирует оператор, используя sp_executesql. У меня есть контроль, чтобы выполнить это вручную, но предпочел бы, чтобы он продолжал генерировать оператор. Я попытался включить EXEC в сгенерированную строку, но я получаю тот же результат .. ie exec sp_executesql N'EXEC dbo.SaveResults ... ' – Patrick

+0

Опубликовать исполняемый файл (то, что вы захватили с помощью SQL Profiler). Мне непонятно, какая проблема сейчас. – usr

+0

Репродукция точно такая же, как описано в исходном сообщении (первый блок кода SQL). Именно это происходит через SQL Profiler. Изменение N'dbo.SaveResults 'в N'EXEC dbo.SaveResults' приводит к тому же сообщению об ошибке «ожидает параметр @resultID». – Patrick

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 строка прошла

Смежные вопросы