程序或功能' x'期望参数' @ y',这是没有提供的。在c#上发生了错误?

时间:2016-12-21 11:35:59

标签: c# asp.net sql-server stored-procedures sqldataadapter

首先,我知道这些问题是重复但是请注意这个期望。 这是我的C#代码,它将错误提升为:

  

程序或功能' aaa'期望参数' @ bbb',这是未提供的。

if (Dt.Rows.Count > 0)
{
    Cmd = new SqlCommand();
    Cmd.CommandText = ("[dbo].[aaa]");
    Cmd.CommandType = CommandType.StoredProcedure;
    Cmd.Parameters.Add("@bbb", SqlDbType.Int).Value = 1;
    Cmd.Parameters.Add("@LettType", SqlDbType.VarChar, 3).Value = LetterType;
    Cmd.Parameters.Add("@IsTajamo", SqlDbType.Char, 1).Value = 1;
    Da = new SqlDataAdapter(Cmd.CommandText, Con);
    Dt.Clear();
    /*Line72:*/    
    Da.Fill(Dt);
}

从技术上讲,我无法找到错误的位置。我通过了所有参数。当我在MS-SQL中单独执行我的存储过程时,它可以正常使用这些值。

您能否请专家帮我解决这个问题? 注意:这是Stored Proc:

   ALTER PROCEDURE [dbo].[aaa] (@bbb Int , @LettType CHAR(3) , @IsTajamo CHAR(1))

AS
BEGIN

select 1


END

注意:(可能这可以帮助,这是我的堆栈跟踪):

  

在System.Data.SqlClient.SqlConnection.OnError(SqlException异常,   布尔值breakConnection,Action 1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action 1 wrapCloseInAction)at   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject   stateObj,Boolean callerHasConnectionLock,Boolean asyncClose)at   System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,   SqlCommand cmdHandler,SqlDataReader dataStream,   BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject   stateObj,布尔& dataReady)at   System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()at   System.Data.SqlClient.SqlDataReader.get_MetaData()at   System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,   RunBehavior runBehavior,String resetOptionsString,Boolean   isInternal,Boolean forDescribeParameterEncryption)at   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(的CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean returnStream,Boolean   async,Int32超时,任务& task,Boolean asyncWrite,Boolean inRetry,   SqlDataReader ds,Boolean describeParameterEncryptionRequest)at   System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String   方法,TaskCompletionSource`1完成,Int32超时,任务&任务,   布尔和放大器; usedCache,Boolean asyncWrite,Boolean inRetry)at   System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String   方法)at   System.Data.SqlClient.SqlCommand.ExecuteReader(的CommandBehavior   行为,String方法)at   System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(的CommandBehavior   行为)   System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(的CommandBehavior   在System.Data.Common.DbDataAdapter.FillInternal(DataSet。)的行为)   dataset,DataTable [] datatables,Int32 startRecord,Int32 maxRecords,   字符串srcTable,IDbCommand命令,CommandBehavior行为)at   System.Data.Common.DbDataAdapter.Fill(DataTable [] dataTables,Int32   startRecord,Int32 maxRecords,IDbCommand命令,CommandBehavior   在System.Data.Common.DbDataAdapter.Fill(DataTable   dataTable)at WebService.Services.GetLettersList(String UserName,   String PassPhrase,String CodeName,String LetterType)in   D:\ Amiri \ WebService \ WebService \ Services.asmx.cs:第79行

2 个答案:

答案 0 :(得分:5)

在你的行中:

Da = new SqlDataAdapter(Cmd.CommandText, Con);

您只传递过程的名称并忽略参数。仅传递Cmd(并将该连接添加到命令中)以使用您定义的参数。

答案 1 :(得分:2)

@Hans Kesting是正确的,但我不认为它解释得很好。发生了什么......

da = new SqlDataAdapter(Cmd.CommandText, Con);

...您是否隐含地创建了与SqlCommand具有相同CommandText的新Cmd。就像你只是使用[dbo].[aaa]作为参数值一样。因此,此新SqlCommand未分配SqlParameters。然后你可以这样做:SqlDataAdapter.SelectCommand.Parameters.Add(....,但这很乱。

您需要做的是使用SqlCommandCmd)本身。但您还必须确保它与连接相关联:

   Cmd = Con.CreateCommand(); //This hooks up the connection to this command
   Cmd.CommandText = "[dbo].[aaa]";
   Cmd.CommandType = CommandType.StoredProcedure;
   Cmd.Parameters.Add("@bbb", SqlDbType.Int).Value = 1;
   Cmd.Parameters.Add("@LettType", SqlDbType.VarChar, 3).Value = LetterType;
   Cmd.Parameters.Add("@IsTajamo", SqlDbType.Char, 1).Value = 1;
   Da = new SqlDataAdapter(Cmd); //Just the command
   Dt.Clear();
   Da.Fill(Dt);