database - 插入前的 SQLite 触发器
问题描述
我正在尝试创建一个触发器,它首先过滤 itemID,然后检查该 itemID 的最高bidNo。bidNo 必须仅比上一个大 +1。投标是投标人。
CREATE TRIGGER new_bid_no
BEFORE INSERT ON BID
BEGIN
SELECT CASE
WHEN (SELECT itemID
FROM bid
WHERE itemID = NEW.itemID
GROUP BY itemID
) AND (SELECT MAX(bidNo) AS bidNo
FROM bid
WHERE NEW.bidNo < bidNo
OR NEW.bidNo = (bidNo+1)
GROUP BY itemID
)THEN
RAISE (ABORT, 'New bid number has to be 1 higher than the last')
END;
END;
投标表
CREATE TABLE BID(
buyerUsername VARCHAR(30) NOT NULL,
itemID INTEGER NOT NULL,
bidNo INTEGER NOT NULL,
bidAmount INTEGER,
bidDate VARCHAR(10),
bidTime TIME,
PRIMARY KEY(buyerUsername, itemID, bidNo),
FOREIGN KEY (buyerUsername) REFERENCES BUYER(buyerUsername),
FOREIGN KEY (itemID) REFERENCES ITEM(itemID)
)
WITHOUT ROWID;
解决方案
首先,您必须定义一个UNIQUE
约束itemID, bidNo
,这只能在CREATE
表的语句中完成,以后不能添加:
CREATE TABLE BID(
buyerUsername TEXT NOT NULL,
itemID INTEGER NOT NULL,
bidNo INTEGER NOT NULL,
bidAmount INTEGER,
bidDate TEXT,
bidTime TEXT,
PRIMARY KEY(buyerUsername, itemID, bidNo),
FOREIGN KEY(buyerUsername) REFERENCES BUYER(buyerUsername),
FOREIGN KEY(itemID) REFERENCES ITEM(itemID),
UNIQUE(itemID, bidNo)
)
WITHOUT ROWID;
我还将您定义为的列的数据类型更改为VARCHAR
,TEXT
因为 SQLite 中没有VARCHAR
数据类型。即使您这样定义它也将是TEXT
. 也没有数据类型TIME
。
现在你的触发器可以这样写:
CREATE TRIGGER new_bid_no
BEFORE INSERT ON BID
WHEN NEW.bidNo <> COALESCE((SELECT MAX(bidNo) FROM bid WHERE itemID = NEW.ItemID AND bidNo < NEW.bidNo), 0) + 1
BEGIN
SELECT RAISE (ABORT, 'New bid number has to be 1 higher than the last');
END
推荐阅读
- pycharm - 使用 GitHub CLI 创建 repo 时是否可以更改、克隆目录?
- reactjs - Reactjs-Popup:无法读取未定义的属性(读取“forwardRef”)
- javascript - JSDOM 环境的 Jest 测试运行器的运行时
- calendar - Apple 日历和 Google 日历 URL 不兼容 URL 太长
- angular - 这是避免参数使用 ENUM 的一种懒惰方式吗?
- amazon-web-services - 从 SQS 队列启动 AWS Batch
- react-native - 错误:无法从 *:\*\*\node_modules\react-native-reanimated\src\Animated.js 解析模块 ./reanimated1:
- asp.net - 在 asp.net core 3 Web 应用程序中针对 HttpPost 方法的 jSon 大摇大摆地显示用户参数值
- python - 为什么不能在熊猫的 for 循环中使用 loc(index+1,'col name')?
- java - 如何返回具有不同元素类型的相同通用集合类型?