我正在为一个学校项目开发一个实时拍卖网站。我们无法对数据库的设计进行任何更改。 “项目”表中有一列用于表示到期日期(拍卖到期日)和到期时间(拍卖到期的确切时间)。它还有一个列,指示拍卖是打开还是关闭。到达到期日期和时间时,必须实时更新此[AuctionClosed?]列。
我们正在使用SQL Server数据库,并且该网站在PHP7上运行。我发现的唯一可能的解决方案是每秒运行一次作业,但这开销太大。
这是我要用于检查列的功能:
CREATE FUNCTION dbo.fn_isAuctionClosed (@Item BIGINT)
RETURNS BIT
AS
BEGIN
DECLARE @expirationDay DATE = (SELECT expirationDate FROM Item WHERE itemId = @Item)
DECLARE @expirationTime TIME = (SELECT expirationTime FROM Item WHERE itemId = @Item)
IF
DATE(GETDATE()) = @expirationDay AND TIME(GETDATE()) >= @expirationTime
OR
DATE(GETDATE()) > @expirationDay
RETURN 1
RETURN 0
END
这是更新列的过程:
CREATE PROCEDURE updateAuctionClosed @Item BIGINT
AS
UPDATE Item
SET [AuctionClosed?] = fn_isAuctionClosed(@Item)
WHERE itemId = @Item
答案 0 :(得分:2)
更具体地说,这里您真正想要的是一个计算列。就像我在评论中所说的那样,由于该列将依赖于当前日期和时间,因此该列将不是确定性的。这意味着它不能为PERSISTED
,而是在每次引用该列时进行计算(PERSISTED
列实际上存储了它的值,并在以某种方式影响和恢复该行时计算出该值)。即使这样,也可以计算如下:
ALTER TABLE Item DROP COLUMN [AuctionClosed?]; --You can't alter a column to a computed column, so we have to DROP it first
ALTER TABLE Item ADD [AuctionClosed?] AS CASE WHEN CONVERT(datetime,expirationDate) + CONVERT(datetime, expirationTime) > GETDATE() THEN 1 ELSE 0 END;
在旁注中,建议不要在对象名称中使用特殊字符。只能使用字母数字字符,并且(如果必须)使用下划线(_
),因为这些字符不会强制标识对象。