说我有桌子:
CREATE TABLE custom_sequence (
name TEXT NOT NULL,
number INTEGER DEFAULT NULL,
is_expired BOOLEAN DEFAULT FALSE
);
在插入时,我必须找到第一个过期的号码并将其放入新记录中。
例如:
"a" 1 FALSE "b" 2 TRUE "c" 3 FALSE
插入新内容:
"c" 2 FALSE
我可以使用TRIGGER做到这一点:
CREATE OR REPLACE FUNCTION write_custom_number()
RETURNS TRIGGER AS
$$
DECLARE
next_number INTEGER;
BEGIN
SELECT
CASE
WHEN count(*) > 0 THEN min(number)
WHEN count(*) = 0 THEN
CASE
WHEN (SELECT
count(*)
FROM custom_sequence) > 0
THEN (SELECT
count(*)
FROM custom_sequence) + 1
WHEN (SELECT
count(*)
FROM custom_sequence) = 0
THEN
1
END
END
INTO next_number
FROM custom_sequence
WHERE is_expired = TRUE;
IF next_number IS NULL
THEN
next_number = 1;
END IF;
NEW.number := next_number;
RETURN NEW;
END
$$
LANGUAGE plpgsql;
CREATE TRIGGER write_custom_number
BEFORE INSERT ON custom_sequence FOR EACH ROW
EXECUTE PROCEDURE write_custom_number();
但是我需要为每个INSERT锁定表格!有没有更好的方法来解决这个问题?
答案 0 :(得分:1)
不,没有解决方法。它是你想要的固有的。您不能重复使用第一个过期的数字并且仍然具有并发性,因为其他人可能会在您提交之前将其插入并插入。
为了使这个并发,您需要某种全局序列管理器,它可以跟踪它已经分发的ID并对表进行脏读以查看其状态。在数据库引擎中没有类似的东西,你无法在SQL级别上执行此操作。它也很难做对。
所以没有。如果您想重新使用ID,则必须按顺序进行交易。