PostgreSQL和JDBC:是否支持“更新表格...返回...进入”?

ruarlubt  于 2022-12-29  发布在  PostgreSQL
关注(0)|答案(5)|浏览(138)

我有一个表,其中有[主键计数器]用于[另一个表中的每页注解]。
这些主键是每页的:* 对于每页 *,注解ID从1开始。
我想原子地分配10个ID来写10个新注解。

  • 我可以用PostgreSQL和JDBC来实现吗?
    (And您是否有任何示例/相关JDBC文档的链接?)
    我只找到了returning如何作为新插入行的主键的示例,使用了一些getGeneratedKeys,这在我的情况下似乎没有用。

我认为SQL UPDATE语句看起来应该是这样的:

update PAGES
set NEXT_COMMENT_ID = NEXT_COMMENT_ID + 10
where PAGE_ID = ?                    <-- next-comment-id is *per page*
returning NEXT_COMMENT_ID into ?

因此,不同的线程和服务器不会尝试重用/覆盖相同的ID(对吗?)

hrirmatl

hrirmatl1#

无需对Statement对象使用execute()getResult()方法即可支持此操作:
如下所示(排除任何错误处理):

String sql = "update ... returning ...";
boolean hasResult = statement.execute(sql);
int affectedRows = 0;
ResultSet rs = null;
if (hasResult) {
  rs = statement.getResultSet();
}
int affectedRows = statement.getUpdateCount();

由于你知道这个语句的作用,这应该没问题。处理一个“未知”的SQL语句有点复杂,因为你需要在一个循环中调用getMoreResults()getUpdateCount()。有关细节,请参见Javadocs。

2nbm6dog

2nbm6dog2#

所以你想要下面的结构?
x =页面主键y =注解主键
页表

x
-
1
2
3
4 etc

备注表

x y
- -
1 1
1 2
1 3
1 4
2 1
2 2 
2 3
etc?

最有意义的做法是在这里使用一个外键结构,并对子记录设置上限。

vlurs2pr

vlurs2pr3#

创建执行update ... returning ... into的存储函数:

create or replace function INC_NEXT_PER_PAGE_REPLY_ID(
  site_id varchar(32), page_id varchar(32), step int) returns int as $$
declare
  next_id int;
begin
  update DW1_PAGES
    set NEXT_REPLY_ID = NEXT_REPLY_ID + step
    where SITE_ID = site_id and PAGE_ID = page_id
    returning NEXT_REPLY_ID into next_id;
  return next_id;
end;
$$ language plpgsql;

并这样称呼它:

statement = connection.prepareCall(
    "{? = call INC_NEXT_PER_PAGE_REPLY_ID(?, ?, ?) }")
statement.registerOutParameter(1, java.sql.Types.INTEGER)
bind(values, statement, firstBindPos = 2)  // bind pos no. 1 is the return value
statement.execute()
nextNewReplyIdAfterwards = statement.getInt(1)

相关文件:

pkwftd7m

pkwftd7m4#

若要使表包含逻辑顺序,则可能需要在子表中创建组合键和外键。

sd=# create table x (x int);
CREATE TABLE
sd=# create table y (x int, y int);
CREATE TABLE

sd=# alter table x add primary key (x);
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "x_pkey" for table "x"
ALTER TABLE
sd=# alter table y add foreign key (x) references x (x);
ALTER TABLE
sd=# alter table y add primary key (x,y);
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "y_pkey" for table "y"
ALTER TABLE

sd=# insert into x values (1);
INSERT 0 1
sd=# insert into x values (2);
INSERT 0 1
sd=# insert into x values (3);
INSERT 0 1
sd=# insert into y values (1,1);
INSERT 0 1
sd=# insert into y values (1,2);
INSERT 0 1
sd=# insert into y values (1,3);
INSERT 0 1
sd=# insert into y values (1,1);
ERROR:  duplicate key value violates unique constraint "y_pkey" 
DETAIL:  Key (x, y)=(1, 1) already exists.

sd=# select * from x;
 x
---
 1
 2
 3
(3 rows)

sd=# select * from y;
 x | y
---+---
 1 | 1
 1 | 2
 1 | 3
(3 rows)

这能让你达到你的目的吗

kwvwclae

kwvwclae5#

你正在做一个更新,但是语句会生成结果,所以使用executeQuery()而不是executeUpdate(),这就是调用之间的真实的区别:executeQuery()处理产生ResultSet的语句;而executeUpdate()返回受影响的行数的计数。

相关问题