在 SQL Server 中,我在檢查約束中檢查多行時遇到問題。
對于投標系統,有一個包含以下列的表:
ObjectID [INT]
BidAmount [NUMERIC(9,2)]
User [VARCHAR(40)]
Date [DATETIME]
我想確保插入的出價高于BidAmount其他出價ObjectID。
我嘗試在檢查約束中使用用戶定義的函式來執行此操作,但是結果證明這非常不可靠(有時允許插入,有時拒絕插入。似乎沒有模式)。
投標表:
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低于同一產品上的其他數量?
uj5u.com熱心網友回復:
CHECK Constraints非常適合在單行上進行檢查。當嘗試訪問目標表或其他表上的其他行時,事情變得復雜。
我強烈認為執行這個邏輯并不是桌子的真正責任。出價就是它們。您可以出價 A=10 美元,隨后的出價 B=20 美元,但隨后檢測到錯誤,您實際上必須將出價 A 更新為 30 美元。那應該怎么辦?可能什么都沒有;另一種方法是將您的問題擴展到包括更新,從而導致更復雜的情況。
相反,運行INSERTs 的用戶有責任正確執行此操作。更有條理的方法是使用程序從用戶/應用程式執行插入。該程序可以在插入之前進行檢查,而throw無需使用觸發器。
uj5u.com熱心網友回復:
我通過在 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
謝謝您的意見。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/478224.html
