我有一张竞标拍卖的表格,而某些拍卖的每个竞标价格应该高于其他拍卖的竞标。 如何才能做到这一点?由于我不知道如何使约束工作,我考虑使用触发器,但没有找到任何具有类似目标(我对sql来说真的很新)。
我的表创建SQL:
CREATE TABLE bid(
id_auction NUMBER(10) NOT NULL,
username VARCHAR(20) NOT NULL,
amount FLOAT NOT NULL,
b_date DATE NOT NULL,
CONSTRAINT pk_bid PRIMARY KEY (id_auction, username, amount),
FOREING KEY (username) REFERENCES user(username),
FOREIGN KEY (id_auction) REFERENCES auction(id_auction)
);
我的不完整触发器:
CREATE OR REPLACE TRIGGER high_bid_trigger
BEFORE INSERT
ON bid
DECLARE
highest_bid NUMBER;
BEGIN
highest_bid := (SELECT min(amount)
FROM bid
WHERE username = :NEW.username
AND id_aution = :NEW.id_auction)
if highest_bid < :NEW:bid
我正在使用Oracle数据库。
答案 0 :(得分:1)
我认为你可以使用触发器来做到这一点。当您从触发器中的同一个表中获取数据时,您可能会遇到变异触发器的问题。这些很难解决。
我不知道它是否可行,但你可以通过存储增量而不是绝对值来解决这个问题。然后,您可以保证增量大于0:
entry
但是,当您想要查询值时,这很麻烦。
另一种选择是在插入触发器后使用来维护另一个表中的数据。因此,拍卖表将包含当前最高出价的列。
然后,您可以在插入触发器之前的中使用此值,其中将使用旧值。
这类问题是我喜欢将数据修改步骤包装到存储过程中的一个示例,而不是通过直接调用constraint chk_t_increment check (increment > 0);
/ update
/ insert
来处理它们。存储过程可以灵活地执行您想要执行的操作而不需要触发器。
答案 1 :(得分:0)
这是应用程序的作业,而不是数据库的作业。
答案 2 :(得分:0)
正如Dudu所说,最好在应用程序级别完成。
如果由于某种原因你必须在数据库中执行此操作,那么最好的选择可能是在提交时快速刷新的物化视图。例如,该视图可以包含所有出价金额的计数,该出价金额严格大于最近的出价金额(按ID分组)。在此物化视图中,您可以拥有一个约束,即所有值必须为零。
每当冒犯&#34;冒犯&#34;尝试插入时,将尝试在物化视图中插入值1。这将被拒绝。这是你的约束!
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::p11_question_id:4233459000346171405
答案 3 :(得分:0)
我会做一个程序来做到这一点:
-- Create Bid Table
CREATE TABLE bid
(
bid_id INTEGER
, bid_amount DECIMAL (6, 2)
, bidder VARCHAR2 (30)
);
-- Use this procedure to make a bid
CREATE OR REPLACE PROCEDURE make_bid (
p_bid_id IN bid.bid_id%TYPE
, p_bid_amount IN bid.bid_amount%TYPE
, p_bidder IN bid.bidder%TYPE
)
AS
-- **********************************************************************
-- Make Bid
-- Purpose:
-- Make a bid on an auction item
-- Arguments:
-- p_bid_id - id of item being bid upon
-- p_bid_amount - amount of the bid
-- p_bidder - account of the bidder
-- Notes:
-- Throws an exception if bid amount does not exceed previous bid
-- **********************************************************************
l_max_previous_bid bid.bid_amount%TYPE;
BEGIN
-- Coalesce is used to set previous bid to 0 if no bids have been made.
SELECT COALESCE (MAX (bid_amount), 0.0)
INTO l_max_previous_bid
FROM bid
WHERE bid_id = p_bid_id;
-- Throw an exception if bid does not exceed previous bid (or zero)
IF p_bid_amount <= l_max_previous_bid
THEN
raise_application_error (
-20001
, 'Bid amount <= TO current bid amount'
|| UTL_TCP.crlf
|| RPAD ('BID_ID', 20)
|| ': '
|| l_max_previous_bid
|| UTL_TCP.crlf
|| RPAD ('Bid Amount', 20)
|| ': '
|| p_bid_amount
|| UTL_TCP.crlf
|| RPAD ('Exisiting Bid Amount', 20)
|| ': '
|| l_max_previous_bid
|| UTL_TCP.crlf
|| RPAD ('Bidder', 20)
|| ': '
|| p_bidder
);
END IF;
-- if we got to here, everything is good
-- Update the record to the new bid
UPDATE bid
SET bidder = p_bidder, bid_amount = p_bid_amount
WHERE bid.bid_id = p_bid_id;
-- if zero rows were updated, there is no existing bid on the object
-- and we need to add a new value.
IF SQL%ROWCOUNT = 0
THEN
INSERT INTO brianl.bid (
bid_id, bid_amount, bidder
)
VALUES (p_bid_id, p_bid_amount, p_bidder);
END IF;
END make_bid;