存储过程在.net中返回异常但在sql server c#winforms中运行正常

时间:2013-09-09 13:14:08

标签: c# sql winforms stored-procedures

为什么以下存储过程会导致.net c#中的问题基本上用于屏幕上的好处报告的性质readonly它在sql server中工作正常,当我勾选为开始日期和结束日期的空值但是当尝试时在我的适配器填充下面执行相同的操作会引发异常

程序:

    public virtual EmployeeBenefitDataset GetBenefitsRecords(int id)
            {
                try
                {

                    EmployeeBenefitDataset ds = new EmployeeBenefitDataset();
                    using (BenefitTableAdapter adpt = new BenefitTableAdapter())
                    {
                        adpt.Connection.ConnectionString = DataAccessLogicHelper.PamsConnectionString;

                        adpt.Fill(ds.BenefitRecords, id, 4, null,null);
                    }
                    return ds;
                }
                catch (Exception ex)
                {
                    Logger.ErrorEntry(ex);
                    throw ex;
                }

存储的proecdure

    GO
    /****** Object:  StoredProcedure [dbo].[hms_GetBenefitRecordsDetails]    Script Date: 09/09/2013 14:09:42 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER PROCEDURE [dbo].[hms_GetBenefitRecordsDetails]
    (
        @empno int,
        @type int,
        @stardate datetime,
        @enddate datetime

    )
    AS
        SET NOCOUNT ON;
      IF NOT @stardate IS NULL
     begin 
     SELECT     benefit.emp_no, benefit.record_id, benefit.contract_id, benefit.career_id, benefit.date_from, benefit.date_to, benefit.benefit_type, benefit.monthly_value, 
                          benefit.benefit_provider, benefit.level_of_cover, benefit.previous_monthly_cost, benefit.benefit_change_details, benefit.current_benefit, benefit.notes, 
                          benefit.level_description, benefit.monthly_annual, benefit.cover_level, benefit.qualifying_reason, benefit_cover_level.desc_ AS benefitcoverdescription, 
                          benefit_provider.desc_ AS benefitproviderdescription,benefit_type.desc_ as benefittypedescription ,employee.benefit_annual_amount,employee.benefit_salary_option,employee.benefit_value
    FROM         benefit INNER JOIN                      
                          benefit_cover_level ON benefit.cover_level = benefit_cover_level.code INNER JOIN
                          benefit_provider ON benefit.benefit_provider = benefit_provider.code INNER JOIN
                           benefit_type ON benefit.benefit_type = benefit_type.code
                           INNER JOIN employee on benefit.emp_no = @empno
                           where benefit.emp_no= @empno   or employee.emp_no= benefit.emp_no
                          and  benefit.benefit_type = @type
     end 
     else
     begin 
     SELECT     benefit.emp_no, benefit.record_id, benefit.contract_id, benefit.career_id, benefit.date_from, benefit.date_to, benefit.benefit_type, benefit.monthly_value, 
                          benefit.benefit_provider, benefit.level_of_cover, benefit.previous_monthly_cost, benefit.benefit_change_details, benefit.current_benefit, benefit.notes, 
                          benefit.level_description, benefit.monthly_annual, benefit.cover_level, benefit.qualifying_reason, benefit_cover_level.desc_ AS benefitcoverdescription, 
                          benefit_provider.desc_ AS benefitproviderdescription,benefit_type.desc_ as benefittypedescription ,employee.benefit_annual_amount,employee.benefit_salary_option,employee.benefit_value
    FROM         benefit INNER JOIN                      
                          benefit_cover_level ON benefit.cover_level = benefit_cover_level.code INNER JOIN
                          benefit_provider ON benefit.benefit_provider = benefit_provider.code INNER JOIN
                           benefit_type ON benefit.benefit_type = benefit_type.code
                           INNER JOIN employee on benefit.emp_no = @empno
                           where benefit.emp_no= @empno   and employee.emp_no= benefit.emp_no


     end 

      IF NOT @stardate IS NULL
     begin 
     SELECT     benefit.emp_no, benefit.record_id, benefit.contract_id, benefit.career_id, benefit.date_from, benefit.date_to, benefit.benefit_type, benefit.monthly_value, 
                          benefit.benefit_provider, benefit.level_of_cover, benefit.previous_monthly_cost, benefit.benefit_change_details, benefit.current_benefit, benefit.notes, 
                          benefit.level_description, benefit.monthly_annual, benefit.cover_level, benefit.qualifying_reason, benefit_cover_level.desc_ AS benefitcoverdescription, 
                          benefit_provider.desc_ AS benefitproviderdescription,benefit_type.desc_ as benefittypedescription ,employee.benefit_annual_amount,employee.benefit_salary_option,employee.benefit_value
    FROM         benefit INNER JOIN                      
                          benefit_cover_level ON benefit.cover_level = benefit_cover_level.code INNER JOIN
                          benefit_provider ON benefit.benefit_provider = benefit_provider.code INNER JOIN
                           benefit_type ON benefit.benefit_type = benefit_type.code
                           INNER JOIN employee on benefit.emp_no = @empno
                           where benefit.emp_no= @empno   and employee.emp_no= benefit.emp_no and
                          benefit.benefit_type = @type and 
    benefit.date_from >= @stardate and benefit.date_to <= @enddate
    end 

3 个答案:

答案 0 :(得分:1)

当您选中复选框以传递空值时,它会显式传递NULL值以及参数。在您当前的代码中,您甚至没有传递参数,这就是异常的原因。

在当前表单中,您的存储过程尚未准备好接受startdate和enddate的NULL值,您应该将过程修改为:

@stardate datetime  = NULL, 
@enddate datetime = NULL

要从C#中传递NULL DateTime,请使用支持DateTime?值的Nullable<DateTime>Null

答案 1 :(得分:1)

SQLC#使用的最短和最长日期不同......此 可以解释您“仅.NET”错误。这些是SQL可以处理的最小值和最大值:

private DateTime minSqlValue = new DateTime(1753, 1, 1, 0, 0, 0);
private DateTime maxSqlValue = DateTime.MaxValue.AddMilliseconds(-3);

请检查正在使用的日期,如果超出此范围,请更新日期。

答案 2 :(得分:0)

这是正确的,问题是ADO.NET看到你传递了一个空值,它有一个System.Object来调用SQL Server DateTime参数的过程,它将尝试映射到System.DateTime,而不是System.Nullable<System.DateTime>。由于System.DateTime不可为空,因此将default(DateTime)发送到该过程。 .NET中的default(DateTime)是“01/01/0001 00:00:00.00”,它与SQL Server的最小DateTime值不匹配

更改存储过程以使用DateTime2。