为什么ExecuteStoredProcedure工作而代码不在?

时间:2016-03-07 14:44:36

标签: c# sql-server stored-procedures

我有一个存储过程,当我运行ExecuteStoredProcedure时,我手动完成。

我有C#代码,当我执行时出现错误:

  

发生了'System.InvalidOperationException'类型的异常   System.Data.dll但未在用户代码中处理。额外   information:String [3]:Size属性的大小无效。

我的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: 

3 个答案:

答案 0 :(得分:2)

目前无法测试任何内容,但我认为您必须为此添加一个长度:

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

如果您指定SqlDbTyp.NVarChar,则需要一个长度(如上所述)

答案 1 :(得分:1)

指定NVarChar输出参数的大小:

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

答案 2 :(得分:0)

@Shnugo和@Alex的帮助我做到了。但是数据集无法感受到数据。 所以我用下面的代码改变并完美地工作。

command.ExecuteNonQuery();

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