我有一个表ContentAddressedFiles
其中列hash
,size
和extension
的组合是UNIQUE
。我想创建一个被调用的存储过程,它会使用给定的值向表中插入一条新记录。如果这些值的记录已经存在,我想只返回该现有记录。这里是我的方法:无法选择UNIQUE VIOLATION的原因
CREATE OR REPLACE FUNCTION INIT_CAF(id_in_case_of_new UUID, _hash VARCHAR(255), _size INTEGER, _extension VARCHAR(255), _mimeType VARCHAR(255))
RETURNS "ContentAddressedFiles"
AS $$
DECLARE
caf "ContentAddressedFiles"%ROWTYPE;
BEGIN
INSERT INTO "ContentAddressedFiles" (id, hash, size, extension, "mimeType", "createdAt", "updatedAt")
VALUES(id_in_case_of_new, _hash, _size, _extension, _mimeType, NOW(), NOW()) RETURNING * INTO caf;
RETURN caf;
EXCEPTION WHEN unique_violation THEN
SELECT * FROM "ContentAddressedFiles" INTO caf WHERE "hash" = _hash AND "size" = _size AND "extension" = _extension;
IF NOT FOUND THEN
RAISE EXCEPTION 'This should never happen.';
END IF;
RETURN caf;
END;
$$ LANGUAGE plpgsql;
然而,当我从打电话并发事务的过程中,我始终得到异常:
EXCEPTION: This should never happen.
这怎么可能?该程序似乎并不能够前SELECT
发生故障的INSERT
的原因(这不是冲突,它是<hash, size, extension>
只是元组中的id
让你看到升起exveption和空值而不是预期的行?..请加你输出的问题 –
是的,正是我得到的异常,当我从不同的事务同时运行的程序。 – DeX3
http://stackoverflow.com/questions/6722344/select-or-insert-a-row-in-one-command –