4

我有一个包含timesheet表的 SQL Server 数据库。该表用于存储员工的角色。在我执行插入之前,我会检查员工在选定的日子里是否有任何预先存在的角色。

这是一个返回预先存在的角色计数的存储过程

set @retVal=(select count(fk_RoleID) from dbo.TimesheetTable where 
(@startdate >=  CAST((
STR( YEAR( StartDate ) ) + '/' +
STR( MONTH( StartDate ) ) + '/' +
STR( DAY( StartDate ) )
)
AS DATE
))-- AND EndDate <= '2012-08-30')
and
(@enddate  <  CAST(
(
STR( YEAR( EndDate ) ) + '/' +
STR( MONTH( EndDate ) ) + '/' +
STR( DAY( EndDate ) )
)
AS DATE
))
and fk_PersonnelID=@personnelID)

return @retVal

以下是一名员工的记录。

pk_ID  fk_PersonnelID  fk_RoleID  StartDate   EndDate     dateCreated
62     1               26         2012-10-01  2012-10-02  2012-10-25 15:55:12.940
81     1               20         2012-10-04  2012-10-06  2012-10-30 14:50:28.300

如果我尝试插入开始日期2012-10-05和结束日期的位置2012-10-11,则查询无法捕获startdate..并且插入发生

我究竟做错了什么?

4

3 回答 3

1

您的重叠测试不正确。测试应该是“两个开始都在相反的结束之前”。记住它,这很容易。

SELECT @retVal = CASE WHEN EXISTS (
    select *
    from dbo.TimesheetTable
    where StartDate <= @EndDate
      and @StartDate <= EndDate
      and fk_PersonnelID=@personnelID) THEN 1 ELSE 0 END

要测试是否存在,请切换到使用 EXISTS,它会短路并在找到结果后立即为您提供结果,而不是对所有匹配项进行计数。

于 2012-10-30T18:25:02.800 回答
0

您不需要解析 StartDate 和 EndDate 列来获得所需的结果。

SELECT @retVal = COUNT(fk_RoleID)
FROM dbo.TimesheetTable AS tt
WHERE @startDate <= tt.EndDate
   AND @endDate >= tt.StartDate
   AND fk_PersonnelId = @personnelID;

return @retVal;

@retVal 对于数据库中已经有计划的输入,这里将返回一个大于 0 的数字。

于 2012-10-30T18:19:47.850 回答
0

您的日期比较不等式中有一个逻辑错误,因为我认为您尝试匹配的日期间隔范围是重叠的 - 没有正确包含 - 正如您的代码似乎假设的那样。

即 10/4 - 10/6 与 10/5- 10/11 严格重叠,而您的代码暗示参数间隔必须完全位于数据行的间隔内。

于 2012-10-30T18:28:16.840 回答