我有这两个表的拍卖应用程序(这显然是高度简化的):
create table auctions (
auction_id int,
end_time datetime
);
create table bids (
bid_id int,
auction_id int,
user_id int,
amount numeric,
bid_time timestamp,
constraint foreign key (auction_id) references auctions (auction_id)
);
拍卖结束后我不希望拍卖。换句话说,只有当bid_time早于该拍卖的end_time时,才应允许出价表中的行。在MySQL中最简单的方法是什么?
答案 0 :(得分:1)
Insert into bids (auction_id, user_id, amount, bid_time)
Select auction_id, [USER_ID], [AMOUNT], [TIMESTAMP]
From auctions
WHERE UNIX_TIMESTAMP() <= UNIX_TIMESTAMP(end_time)
当然你必须替换'[]'值
答案 1 :(得分:1)
很遗憾,MySQL没有CHECK
约束功能。但是您应该能够使用触发器强制执行此操作。但是,MySQL触发器支持不像其他RDBMS-es那样先进或优化得很好,如果你这样做,你将遭受相当大的性能损失。因此,如果这是一个拥有大量并发用户的实时交易系统,您应该寻找另一种解决方案。
CREATE TRIGGER bir_bids
BEFORE INSERT ON bids
FOR EACH ROW
BEGIN
DECLARE v_end_time datetime;
-- declare a custom error condition.
-- SQLSTATE '45000' is reserved for that.
DECLARE ERR_AUCTION_ALREADY_CLOSED CONDITION FOR SQLSTATE '45000';
SELECT end_time INTO v_end_time
FROM auctions
WHERE auction_id = NEW.auction_id;
-- the condition is written like this so that a signal is raised
-- only in case the bid time is greater than the auction end time.
-- if either bid time or auction end time are NULL, no signal will be raised.
-- You should avoid complex NULL handling here if bid time or auction end time
-- must not be NULLable - simply define a NOT NULL column constraint for those cases.
IF NEW.bid_time > v_end_time THEN
SIGNAL ERR_AUCTION_ALREADY_CLOSED;
END IF;
END:
请注意,SIGNAL
语法仅在MySQL 5.5(当前为GA)后才可用。自MySQL 5.0以来,触发器可用。因此,如果您需要在5.5之前的MySQL版本中实现此功能,则需要破解无法发出信号的方法。您可以通过在数据中进行一些更改来保证INSERT
失败。例如,你可以写:
IF NEW.bid_time > v_end_time THEN
SET NEW.auction_id = NULL;
END IF;
由于表中acution_id
被声明为NOT NULL
,因此数据的状态将无法插入。缺点是您将获得NOT NULL约束违规,并且应用程序将不得不猜测这是由于此触发器触发还是由于“真正的”NOT NULL约束违规。
有关详细信息,请参阅:http://rpbouman.blogspot.nl/2009/12/validating-mysql-data-entry-with_15.html和http://rpbouman.blogspot.nl/2006/02/dont-you-need-proper-error-handling.html
答案 2 :(得分:0)
而是做一个简单的事情创建一个列名状态。将其类型设置为枚举。当你想阻止它时,将其值更新为0.默认值应为1表示打开。 0表示已关闭