我的数据库是PostgreSQL。语言是Java
表名为phrase
,列名为name
。
许多用户在任何时候都会在此表中插入许多行 我们需要确保某个领域是独一无二的 如果在加载过程中发现了这样的字段,我想返回行ID。
例如,我可以将字段设为唯一主键,并在插入行ID时捕获异常并查找现有行。
但我认为这是个坏主意。
我可以先查找该行,然后插入。
但是,我们怎样才能避免并发交易相互影响?
下载时,批量下载是否更好,如何在PostgreSQL中执行此操作?我甚至不知道。
答案 0 :(得分:2)
您可以创建UNIQUE
约束和INSERT ... ON CONFLICT
:
CREATE TABLE mytable (
id integer PRIMARY KEY,
name text NOT NULL
CONSTRAINT name_unique UNIQUE
);
INSERT INTO mytable (id, name)
VALUES (1, 'me');
现在运行批处理INSERT
,返回每个影响行的id
,运行
INSERT INTO mytable (id, name)
VALUES (2, 'me'),
(3, 'new')
ON CONFLICT (name)
DO UPDATE SET name = EXCLUDED.name
RETURNING id;
如果您希望UPDATE
返回,则实际上不会更改行的奇怪id
。
答案 1 :(得分:1)
您可以使用PostgreSQL中提供的INSERT ... ON CONFLICT DO NOTHING
子句,而不是捕获异常。通过检查受影响的行数(PreparedStatement.executeUpdate
的返回码),您可以检测是否存在冲突。
E.g。
PreparedStatement pstmt = conn.prepareStatement("insert into x values (?,?) on conflict do nothing");
pstmt.setInt(1, myId);
pstmt.setInt(2, myValue);
int rc = pstmt.executeUpdate();
if (rc == 0) {
// fetch the existing row...
}