在 table 中为状态存储 Where 子句
Storing Where clause in a table for a status
考虑以下 tables:
Item(id, dueDate)
DueStatus(id, code, whereClause)
DueStatus table 具有以下值:
1/OVERDUE/'dueDate < getdate()'
2/DUE/'dueDate = getdate()'
想法是将 where 子句存储在 table 中,然后使用它创建动态 SQL 以针对所有不同状态执行。
与手写查询相比,以这种方式执行此操作是否有好处?
目标是能够添加 DueStatus,例如 3/NEXTFIVEDAYS/'dueDate = dateadd(day,datediff(day,-5,@currentDate),0)'
,而无需更改存储过程。
我以前没有走过这条路,想确保我没有遗漏一些重要的东西。
我不会那样做。问题出现在更新 where 列:
- 如果列名发生变化怎么办?
- 如果您想在 where 子句中添加另一个条件怎么办?然后,您必须逐行进行,或者无论如何都要从您尝试 运行 的根源开始。
- 你的where子句有多少个条件?
查看以上评论了解更多不这样做的原因。
我发现这对于基于两个日期之间的差异的动态状态来说是一个有趣的挑战。我想到了这个。虽然对于大多数用例来说可能不是 100%,但也许它是您可以使用的东西。
CREATE TABLE [dbo].[Items](
[ID] [int] NULL,
[DueDate] [date] NULL
) ON [PRIMARY]
INSERT INTO dbo.Items(ID, DueDate) VALUES (1, '12/1/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (2, '12/2/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (3, '12/6/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (4, '12/6/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (5, '12/10/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (6, '2/1/2019')
INSERT INTO dbo.Items(ID, DueDate) VALUES (7, '1/1/2013')
INSERT INTO dbo.Items(ID, DueDate) VALUES (8, '12/5/2018')
CREATE TABLE [dbo].[Statuses](
[DayDifference] [int] NULL,
[StatusText] [varchar](32),
)
INSERT INTO dbo.Statuses(DayDifference, StatusText) VALUES(0, 'On Time')
INSERT INTO dbo.Statuses(DayDifference, StatusText) VALUES(1, '1 Day Late')
INSERT INTO dbo.Statuses(DayDifference, StatusText) VALUES(5, '5 Days Late')
;WITH Data AS (
SELECT i.ID AS ItemID,
i.DueDate,
DATEDIFF(DAY, i.DueDate, GETDATE()) AS DayDifference
FROM dbo.Items i
WHERE DATEDIFF(DAY, i.DueDate, GETDATE()) >= 0 -- Just get the on-times and lates.
)
SELECT d.ItemID,
d.DayDifference AS DaysLate,
CASE WHEN s.StatusText IS NULL
THEN 'Unknown'
ELSE s.StatusText
END AS StatusText
FROM Data d
LEFT JOIN dbo.Statuses s ON d.DayDifference = s.DayDifference
结果如下,当运行今天,2018-12-06:
ItemID DaysLate StatusText
-------------------------------
1 5 5 Days Late
2 4 Unknown
3 0 On Time
4 0 On Time
7 2165 Unknown
8 1 1 Day Late
请注意,这是一个起点,可能需要根据您的具体用例进行调整。
考虑以下 tables:
Item(id, dueDate)
DueStatus(id, code, whereClause)
DueStatus table 具有以下值:
1/OVERDUE/'dueDate < getdate()'
2/DUE/'dueDate = getdate()'
想法是将 where 子句存储在 table 中,然后使用它创建动态 SQL 以针对所有不同状态执行。
与手写查询相比,以这种方式执行此操作是否有好处?
目标是能够添加 DueStatus,例如 3/NEXTFIVEDAYS/'dueDate = dateadd(day,datediff(day,-5,@currentDate),0)'
,而无需更改存储过程。
我以前没有走过这条路,想确保我没有遗漏一些重要的东西。
我不会那样做。问题出现在更新 where 列:
- 如果列名发生变化怎么办?
- 如果您想在 where 子句中添加另一个条件怎么办?然后,您必须逐行进行,或者无论如何都要从您尝试 运行 的根源开始。
- 你的where子句有多少个条件?
查看以上评论了解更多不这样做的原因。
我发现这对于基于两个日期之间的差异的动态状态来说是一个有趣的挑战。我想到了这个。虽然对于大多数用例来说可能不是 100%,但也许它是您可以使用的东西。
CREATE TABLE [dbo].[Items](
[ID] [int] NULL,
[DueDate] [date] NULL
) ON [PRIMARY]
INSERT INTO dbo.Items(ID, DueDate) VALUES (1, '12/1/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (2, '12/2/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (3, '12/6/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (4, '12/6/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (5, '12/10/2018')
INSERT INTO dbo.Items(ID, DueDate) VALUES (6, '2/1/2019')
INSERT INTO dbo.Items(ID, DueDate) VALUES (7, '1/1/2013')
INSERT INTO dbo.Items(ID, DueDate) VALUES (8, '12/5/2018')
CREATE TABLE [dbo].[Statuses](
[DayDifference] [int] NULL,
[StatusText] [varchar](32),
)
INSERT INTO dbo.Statuses(DayDifference, StatusText) VALUES(0, 'On Time')
INSERT INTO dbo.Statuses(DayDifference, StatusText) VALUES(1, '1 Day Late')
INSERT INTO dbo.Statuses(DayDifference, StatusText) VALUES(5, '5 Days Late')
;WITH Data AS (
SELECT i.ID AS ItemID,
i.DueDate,
DATEDIFF(DAY, i.DueDate, GETDATE()) AS DayDifference
FROM dbo.Items i
WHERE DATEDIFF(DAY, i.DueDate, GETDATE()) >= 0 -- Just get the on-times and lates.
)
SELECT d.ItemID,
d.DayDifference AS DaysLate,
CASE WHEN s.StatusText IS NULL
THEN 'Unknown'
ELSE s.StatusText
END AS StatusText
FROM Data d
LEFT JOIN dbo.Statuses s ON d.DayDifference = s.DayDifference
结果如下,当运行今天,2018-12-06:
ItemID DaysLate StatusText
-------------------------------
1 5 5 Days Late
2 4 Unknown
3 0 On Time
4 0 On Time
7 2165 Unknown
8 1 1 Day Late
请注意,这是一个起点,可能需要根据您的具体用例进行调整。