检查列值是否高于具有相应列的其他行
Check if column value is higher than other rows with corresponding columns
在 SQL 服务器中,我在检查约束中的多行时遇到问题。
对于出价系统,table 包含以下列:
ObjectID [INT]
BidAmount [NUMERIC(9,2)]
User [VARCHAR(40)]
Date [DATETIME]
我想确保插入的出价 BidAmount
高于此 ObjectID
的其他出价。
我尝试在检查约束中使用用户定义的函数来执行此操作,但事实证明这非常不可靠(有时允许插入,有时被拒绝。似乎没有模式).
出价table:
CREATE TABLE Bid
(
ObjectID INT NOT NULL,
BidAmount NUMERIC(9,2) NOT NULL,
User VARCHAR(40) NOT NULL,
Date DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT PK_Bod
PRIMARY KEY (ObjectID, BidAmount),
CONSTRAINT FK_Bod_User
FOREIGN KEY (User) REFERENCES User (Username),
CONSTRAINT FK_Bod_Object
FOREIGN KEY (ObjectID) REFERENCES Object (ObjectID),
CONSTRAINT AK_Bod_Gebruikersmoment UNIQUE (User, Date),
CONSTRAINT AK_Bod_Voorwerpmoment UNIQUE (ObjectID, Date),
CONSTRAINT CK_Bodhoogte
CHECK (BidAmount > dbo.krijgMinimaleBod(ObjectID, Date))
)
我尝试使用的用户自定义函数:
CREATE FUNCTION dbo.krijgMinimaleBod (@ObjectID INT)
RETURNS NUMERIC(9,2)
AS
BEGIN
DECLARE @highestBid NUMERIC(9,2)
SELECT @highestBid = ISNULL(MAX(BidAmount), V.StartPrice)
FROM Object V
LEFT JOIN Bid B ON B.ObjectID = V.ObjectID
WHERE V.ObjectID = @ObjectID
GROUP BY V.ObjectID, V.StartPrice;
RETURN @highestBid
END
我该如何防止系统插入的行中 BidAmount
低于同一产品的其他数量?
CHECK Constraints
非常适合在单行上进行检查。尝试访问目标 table 或其他目标上的其他行时,事情会变得复杂。
我强烈认为执行此逻辑并不是 table 的真正责任。出价是什么。您可以让出价 A=10$,随后的出价 B=20$,但随后检测到错误,您实际上必须将出价 A 更新为 30$。那应该怎么办?可能什么都没有;另一种方法是扩展您的问题以包括更新,从而导致更复杂的情况。
相反,运行 INSERT
s 的用户有责任正确执行此操作。更有条理的方法是使用过程从 user/application 执行插入。此过程可以在插入之前进行检查,并且 throw
无需使用触发器。
我在 T-SQL 中使用触发器解决了这个问题。
CREATE TRIGGER Bid_HighEnough ON dbo.Bod
AFTER INSERT, UPDATE
AS
IF EXISTS (SELECT 'Wrong'
FROM Inserted I INNER JOIN Bid B
ON I.ObjectID = B.ObjectID
INNER JOIN Object V
ON I.ObjectID = V.ObjectID
WHERE I.BidAmount < V.StartPrice OR I.BidAmount < B.BidAmount
BEGIN
THROW 50000, 'No bids allowed lower than previous bids.', 1
END
感谢您的评论。
在 SQL 服务器中,我在检查约束中的多行时遇到问题。
对于出价系统,table 包含以下列:
ObjectID [INT]
BidAmount [NUMERIC(9,2)]
User [VARCHAR(40)]
Date [DATETIME]
我想确保插入的出价 BidAmount
高于此 ObjectID
的其他出价。
我尝试在检查约束中使用用户定义的函数来执行此操作,但事实证明这非常不可靠(有时允许插入,有时被拒绝。似乎没有模式).
出价table:
CREATE TABLE Bid
(
ObjectID INT NOT NULL,
BidAmount NUMERIC(9,2) NOT NULL,
User VARCHAR(40) NOT NULL,
Date DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT PK_Bod
PRIMARY KEY (ObjectID, BidAmount),
CONSTRAINT FK_Bod_User
FOREIGN KEY (User) REFERENCES User (Username),
CONSTRAINT FK_Bod_Object
FOREIGN KEY (ObjectID) REFERENCES Object (ObjectID),
CONSTRAINT AK_Bod_Gebruikersmoment UNIQUE (User, Date),
CONSTRAINT AK_Bod_Voorwerpmoment UNIQUE (ObjectID, Date),
CONSTRAINT CK_Bodhoogte
CHECK (BidAmount > dbo.krijgMinimaleBod(ObjectID, Date))
)
我尝试使用的用户自定义函数:
CREATE FUNCTION dbo.krijgMinimaleBod (@ObjectID INT)
RETURNS NUMERIC(9,2)
AS
BEGIN
DECLARE @highestBid NUMERIC(9,2)
SELECT @highestBid = ISNULL(MAX(BidAmount), V.StartPrice)
FROM Object V
LEFT JOIN Bid B ON B.ObjectID = V.ObjectID
WHERE V.ObjectID = @ObjectID
GROUP BY V.ObjectID, V.StartPrice;
RETURN @highestBid
END
我该如何防止系统插入的行中 BidAmount
低于同一产品的其他数量?
CHECK Constraints
非常适合在单行上进行检查。尝试访问目标 table 或其他目标上的其他行时,事情会变得复杂。
我强烈认为执行此逻辑并不是 table 的真正责任。出价是什么。您可以让出价 A=10$,随后的出价 B=20$,但随后检测到错误,您实际上必须将出价 A 更新为 30$。那应该怎么办?可能什么都没有;另一种方法是扩展您的问题以包括更新,从而导致更复杂的情况。
相反,运行 INSERT
s 的用户有责任正确执行此操作。更有条理的方法是使用过程从 user/application 执行插入。此过程可以在插入之前进行检查,并且 throw
无需使用触发器。
我在 T-SQL 中使用触发器解决了这个问题。
CREATE TRIGGER Bid_HighEnough ON dbo.Bod
AFTER INSERT, UPDATE
AS
IF EXISTS (SELECT 'Wrong'
FROM Inserted I INNER JOIN Bid B
ON I.ObjectID = B.ObjectID
INNER JOIN Object V
ON I.ObjectID = V.ObjectID
WHERE I.BidAmount < V.StartPrice OR I.BidAmount < B.BidAmount
BEGIN
THROW 50000, 'No bids allowed lower than previous bids.', 1
END
感谢您的评论。