2016-03-07 81 views
1

我有一个存储过程,当我运行ExecuteStoredProcedure作品时手动完美。为什么ExecuteStoredProcedure有效,下面的代码不是?

我有C#代码,当我执行我得到一个错误:

An exception of type 'System.InvalidOperationException' occurred in System.Data.dll but was not handled in user code. Additional information: String[3]: the Size property has an invalid size of 0.

我的C#代码:

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString)) 
using (SqlCommand command = connection.CreateCommand()) 
{ 
    command.CommandText = "[dbo].[CACustomerControl]"; 
    command.CommandType = CommandType.StoredProcedure; 

    command.Parameters.Add("@CANo", SqlDbType.NVarChar, 50, CANo).Value = CANo.text; 
    command.Parameters.Add("@CAPass", SqlDbType.NVarChar, 50, CAPass).Value = CAPass.text; 
    command.Parameters.Add("@TermiIMEI ", SqlDbType.NVarChar, 50, TermiIMEI).Value = TermiIMEI; 

    command.Parameters.Add("@CustName", SqlDbType.NVarChar).Direction = ParameterDirection.Output; 
    command.Parameters.Add("@CustSurName", SqlDbType.NVarChar).Direction = ParameterDirection.Output; 
    command.Parameters.Add("@Amount", SqlDbType.Int).Direction = ParameterDirection.Output; 
    command.Parameters.Add("@StatusCode", SqlDbType.Int).Direction = ParameterDirection.Output; 

    connection.Open(); 

    DataSet ds = new DataSet(); 
    SqlDataAdapter sqlda = new SqlDataAdapter(command); 

    sqlda.Fill(ds); 

    command.Dispose(); 
    connection.Close(); 
    connection.Dispose(); 
} 

我的存储过程:

/*parameters*/ 
ALTER Procedure [dbo].[CACustomerControl]( 
    @CANo nvarchar(50), 
    @CAPass nvarchar(50), 
    @TermiIMEI nvarchar(50), 
    @CustName nvarchar(50) output, 
    @CustSurName nvarchar(50) output, 
    @Amount int output, 
    @StatusCode int output 
) 
AS 
BEGIN 
    /*internal of sp*/ 
     DECLARE 
     @CustId int, 
     @TermiId int, 
     @PassId int, 
     @CAId int, 
     @LocationId int 

    /* GET CUSTOMER NAME and CUSTOMER SURNAME */ 
    SELECT 
     @CustName = CUS.CustomerName, 
     @CustSurName = CUS.CustomerSurname 
    FROM 
     dbo.CABASIM C 
    INNER JOIN 
     dbo.CUSTOMERS CUS ON C.CACustomer = CUS.CUSTID 
    INNER JOIN 
     dbo.CANOLIST CNLIST ON CNLIST.ENOID = C.CANo 
    INNER JOIN 
     dbo.CAPASSLIST CPLIST ON CPLIST.PASID = C.CAPassword 
    WHERE 
     CNLIST.CANo = @CANo 
     AND CPLIST.CAPassowrd = @CAPass 

    /* GET AMOUNT */ 
    SELECT 
     @Amount = PT.PaymentAmount 
    FROM 
     dbo.TERMI P 
    INNER JOIN 
     dbo.PAYMENT PT ON P.TermiLocation = PT.PaymentLocation 
    WHERE 
     P.TermiIMEI = @TermiIMEI 

    /* GET CA ID */ 
    SELECT @CAId = ECLIST.ENOID 
    FROM dbo.CANOLIST ECLIST 
    WHERE ECLIST.CANo = @CANo 

    /* GET LOCATION ID and GET TERMI ID */ 
    SELECT @LocationId = PLIST.TermiLocation, @TermiId = PLIST.TERMIID 
    FROM TERMI PLIST 
    WHERE PLIST.TermiIMEI = @TermiIMEI 

    if (@CustName is not null and @CustSurName is not null and @Amount is not null) 
    begin 
     set @StatusCode=1 

     INSERT INTO [dbo].[LOG]([LogCA], [LogTermiIMEI], [LogResult],[LogDate], [LogTime], [LogTermiLocation], [LogAmount]) 
     VALUES (@CAId, @TermiId, 1, CONVERT (date, GETDATE()), CONVERT (time, GETDATE()), @LocationId, @Amount) 
    end 
    else 
    begin 
     set @StatusCode = 0 

     if (@StatusCode = 0) 
     begin 
      INSERT INTO [dbo].[LOG]([LogCA], [LogTermiIMEI], [LogResult],[LogDate], [LogTime], [LogTermiLocation], [LogAmount]) 
      VALUES (@CAId, @TermiId, 0, CONVERT (date, GETDATE()), CONVERT (time, GETDATE()), @LocationId, 0) 
     end 
    end 
END 

调用堆栈

System.InvalidOperationException was unhandled by user code 
    HResult=-2146233079 
    Message=String[3]: the Size property has an invalid size of 0. 
    Source=System.Data 
    StackTrace: 
     at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc) 
     at System.Data.SqlClient.SqlCommand.SetUpRPCParameters(_SqlRPC rpc, Int32 startCount, Boolean inSchema, SqlParameterCollection parameters) 
     at System.Data.SqlClient.SqlCommand.BuildRPC(Boolean inSchema, SqlParameterCollection parameters, _SqlRPC& rpc) 
     at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest) 
     at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) 
     at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) 
     at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) 
     at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) 
     at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior) 
     at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) 
     at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) 
     at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet) 

     at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters) 
     at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) 
     at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) 
    InnerException: 
+0

哪里(哪一行)引发此错误?你是否试图设定一个突破点并逐步完成?您是否尝试让异常停止执行并查看调用堆栈? – Shnugo

+0

@Shnugo yes sqlda.Fill(ds);在这一行我得到错误 – NTMS

+0

我将更新我的问题调用堆栈 – NTMS

回答

2

无法测试此刻什么,但我认为你必须添加的长度到这一点:

command.Parameters.Add("@CustName", SqlDbType.NVarChar).Direction = ParameterDirection.Output; 
command.Parameters.Add("@CustSurName", SqlDbType.NVarChar).Direction = ParameterDirection.Output; 

如果specifiy SqlDbTyp.NVarChar你需要一个长度(如上所述)

+0

是的,它的工作,但我没有得到任何回报。 sqlda.Fill(DS);是空的,没有桌子。如果我在sql中运行(执行sp)并输入3参数值,我会得到一个结果。我不明白发生了什么,为什么不能在我的C#代码中工作? – NTMS

1

指定的的NVarChar输出PARAMS大小:

command.Parameters.Add("@CustSurName", SqlDbType.NVarChar, 50).Direc... 
+0

谢谢亚历克斯。它的工作,但我没有得到任何回报。 – NTMS

0

@Shnugo和@Alex的帮助我让它工作。但数据集感觉不到数据。 所以我改变下面的代码,并完美地工作。

command.ExecuteNonQuery(); 

// read output value 
object CustomerName = command.Parameters["@CustName"].Value;