我在网站上有一个搜索页面的SQL存储过程,用户可以在两个日期字段之间和之间搜索记录:initiatedDateStart和initiatedDateEnd。 SQL查询的逻辑应如下所示:
由于我不是SQL专家,我的存储过程不是很优雅或聪明,但它会返回我期望的记录,但日期字段除外。我已经研究过这个,但语法和逻辑让我感到难过。这是我的存储过程的片段。如果在initStartDate texbox中输入了值,但initEndDate为空,则返回在开始日期之后创建的所有记录。我很感激这方面的任何帮助。
DECLARE @initStartDate datetime = NULL
DECLARE @initEndDate datetime = NULL
SELECT DISTINCT
d.[DCRId],
d.[Title],
d.[FiscalYear]
FROM [dbo].[tblDCR] d
LEFT OUTER JOIN [dbo].[tblWorkflow] orig ON (d.[DCRId] = orig.[DCRId] AND orig.StepName = 'Draft')
WHERE 1 = 1
AND (orig.BadgeDate >= @initStartDate OR @initStartDate IS NULL)
AND (orig.BadgeDate <= @initEndDate OR @initEndDate IS NULL)
答案 0 :(得分:2)
我能想到的最好的方法是使用动态sql
DECLARE @initStartDate datetime = NULL;
DECLARE @initEndDate datetime = NULL;
Declare @Sql NVARCHAR(MAX);
SET @Sql = N'SELECT DISTINCT
d.[DCRId],
d.[Title],
d.[FiscalYear]
FROM [dbo].[tblDCR] d
LEFT OUTER JOIN [dbo].[tblWorkflow] orig
ON (d.[DCRId] = orig.[DCRId] AND orig.StepName = ''Draft'')
WHERE 1 = 1 '
+ CASE WHEN @initStartDate IS NOT NULL THEN
N' AND orig.BadgeDate >= @initStartDate ' ELSE N'' END
+ CASE WHEN @initEndDate IS NOT NULL THEN
N' AND orig.BadgeDate <= @initEndDate ' ELSE N'' END
Exec sp_executesql @Sql
,N'@initStartDate datetime, @initEndDate datetime'
,@initStartDate
,@initEndDate
答案 1 :(得分:0)
但如果@initStartDate没有值怎么办? 如果没有startDate条件,假设您希望它一直返回,那么,将日期条件作为Nullable参数传递,如下所示: 然后,(假设数据库字段只是没有时间的日期),请使用以下where子句:
where orig.BadgeDate Between
Coalesce(@initStartDate, orig.BadgeDate) and
Coalesce(@initEndDate, @initStartDate, orig.BadgeDate)
答案 2 :(得分:0)
我认为您的问题的解决方案是将当前日期分配给结尾参数时保留为NULL。通过这样做,用户可以输入任何参数并获取当前日期值,仅输入开始日期并获取开始日期的数据,或输入结束日期并获取当前日期和结束日期之间的数据。作为最后一个问题,如果由于某种原因用户提出的开始日期高于结束日期,您可以告诉程序仅返回今天的数据。
CREATE PROCEDURE test_proc
@initStartDate date = null,
@initEndDate date = null
AS
IF @initStartDate IS NULL AND @initEndDate IS NULL
BEGIN
SET @initStartDate = (SELECT GETDATE())
SET @initEndDate = @initStartDate
END
ELSE IF @initStartDate IS NULL AND @initEndDate IS NOT NULL
BEGIN
SET @initStartDate = @initEndDate
END
ELSE IF @initEndDate IS NULL AND @initStartDate IS NOT NULL
BEGIN
SET @initEndDate = @initStartDate
END
IF @initStartDate > @initEndDate
BEGIN
SET @initStartDate = (SELECT GETDATE())
SET @initEndDate = @initStartDate
END
SELECT DISTINCT
d.[DCRId],
d.[Title],
d.[FiscalYear]
FROM [dbo].[tblDCR] d
LEFT OUTER JOIN [dbo].[tblWorkflow] orig ON (d.[DCRId] = orig.[DCRId] AND orig.StepName = 'Draft')
WHERE orig.BadgeDate BETWEEN @initStartDate AND @initEndDate
GO
DECLARE @initStartDate date = '10/21/15'
DECLARE @initEndDate date = NULL
IF @initStartDate IS NULL AND @initEndDate IS NOT NULL
BEGIN
SET @initStartDate = @initEndDate
END
ELSE IF @initEndDate IS NULL AND @initStartDate IS NOT NULL
BEGIN
SET @initEndDate = @initStartDate
END
SELECT DISTINCT
d.[DCRId],
d.[Title],
d.[FiscalYear]
FROM [dbo].[tblDCR] d
LEFT OUTER JOIN [dbo].[tblWorkflow] orig ON (d.[DCRId] = orig.[DCRId] AND orig.StepName = 'Draft')
WHERE 1 = 1
AND (orig.BadgeDate BETWEEN @initStartDate AND @initEndDate) OR (@initStartDate IS NULL OR @initEndDate IS NULL)