postgresql在单个查询中更新多个表

postgresql在单个查询中更新多个表,sql,postgresql,sql-update,common-table-expression,Sql,Postgresql,Sql Update,Common Table Expression,我有以下两个表格: 序列表 id CHARACTER VARYING(20), serial_key CHARACTER VARYING(20), PRIMARY KEY(id, serial_key) 序列速率: id CHARACTER VARYING(20), serial_key CHARACTER VARYING(20), rate NUMERIC, PRIMARY KEY(id, serial_key), FOREIGN KEY (id, serial_key) REFEREN

我有以下两个表格:

  • 序列表

    id CHARACTER VARYING(20),
    serial_key CHARACTER VARYING(20),
    PRIMARY KEY(id, serial_key)
    
  • 序列速率:

    id CHARACTER VARYING(20), 
    serial_key CHARACTER VARYING(20),
    rate NUMERIC,
    PRIMARY KEY(id, serial_key),
    FOREIGN KEY (id, serial_key) REFERENCES serial_table(id, serial_key)
    
  • 现在我想从单个SQL查询更新
    serial\u rate.rate
    serial\u表.serial\u key
    ,如下所示:

    UPDATE inventory.serial_table AS s 
    JOIN inventory.serial_rate AS r 
    ON (s.id, s.serial_key) = (r.id, r.serial_key) 
    SET s.serial_key = '0002', r.rate = 22.53
    WHERE (s.id, s.serial_key) = ('01', '002');
    
    我知道这是不正确的是否有一种可能的方法来执行此操作,因为我想使用该语句在Java中创建一个
    PreparedStatement

    编辑 这个问题不是关于Java中的
    PreparedStatements
    ,而是关于我希望在创建
    PreparedStatement
    时作为参数传递的SQL语法我不想得到任何关于
    PreparedStatement

    的答案这是一个CTE的东西(但我不知道如何将它包装成一个准备好的Java东西)


    这是一匹没有名字的马在sqlfiddle.com上发布的:

       WITH id_values (new_key, old_key, id) as (
          values ('0002', '002', '01')
        ), src AS (
          UPDATE serial_rate
              SET rate = 22.53, 
                  serial_key = (select new_key from id_values)
          WHERE serial_key = (select old_key from id_values)
            AND id = (select id from id_values)
          RETURNING *
        )
        UPDATE serial_table dst
           SET serial_key = src.serial_key
        FROM src
        WHERE dst.id = (select id from id_values)
          AND dst.serial_key = (select old_key from id_values)
        ;
    

    这实际上是wildplasser发布的内容的一个修改版本,作为对我的问题的回答,
    serial\u key
    字段是否可以使用一次。

    您真的打算更新PK组件
    serial\u table.serial\u key
    ?和:
    serial\u rate.serial\u key
    是否也应更新(也是PK组件,FK为第一个)?如果没有,则可能违反FK约束。@wildplasser第一个答案是“是”,第二个答案是“删除限制”时FK处于更新级联状态。可能重复@JarrodRoberson我无法理解为什么您认为此问题与您链接的问题相似?我没有在该链接中得到我想要的答案。如果您的问题只是关于SQL语法,我会删除所有关于“准备语句”的提及。这仍然是两条语句,现在还不清楚它们只是在一个事务/存储过程中执行两条更新语句,并且作为一条准备语句更难实现(想想一个到处都是变量的丑陋的长字符串)不,它们是链接在一起的(相当笨拙)。提示:只有一个分号。只需将
    EXPLAIN
    放在它前面,您就会看到它将为组合更新生成一个查询计划。但它实际上是一个子查询,对吗?它是两个查询和一个查询计划?@DanField:不,它只是一个查询。当然,它只有一个查询计划。诀窍是组合在第一个UPDATE命令中使用CTE选项和RETURN选项,这将在第二个UPDATE命令中使用。@Blip:是的,在查询中使用另一个CTE选项是可能的:
       WITH id_values (new_key, old_key, id) as (
          values ('0002', '002', '01')
        ), src AS (
          UPDATE serial_rate
              SET rate = 22.53, 
                  serial_key = (select new_key from id_values)
          WHERE serial_key = (select old_key from id_values)
            AND id = (select id from id_values)
          RETURNING *
        )
        UPDATE serial_table dst
           SET serial_key = src.serial_key
        FROM src
        WHERE dst.id = (select id from id_values)
          AND dst.serial_key = (select old_key from id_values)
        ;