为什么以下存储过程会导致.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
答案 0 :(得分:1)
当您选中复选框以传递空值时,它会显式传递NULL
值以及参数。在您当前的代码中,您甚至没有传递参数,这就是异常的原因。
在当前表单中,您的存储过程尚未准备好接受startdate和enddate的NULL
值,您应该将过程修改为:
@stardate datetime = NULL,
@enddate datetime = NULL
要从C#中传递NULL
DateTime
,请使用支持DateTime?
值的Nullable<DateTime>
或Null
。
答案 1 :(得分:1)
SQL
和C#
使用的最短和最长日期不同......此 可以解释您“仅.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。