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

Bli*_*lip 7 sql postgresql common-table-expression sql-update

我有2个表格如下:

  1. serial_table

    id CHARACTER VARYING(20),
    serial_key CHARACTER VARYING(20),
    PRIMARY KEY(id, serial_key)
    
    Run Code Online (Sandbox Code Playgroud)
  2. serial_rate:

    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)
    
    Run Code Online (Sandbox Code Playgroud)

现在我想更新serial_rate.rateserial_table.serial_key从单个SQL查询更新,如:

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');
Run Code Online (Sandbox Code Playgroud)

我知道的是不正确的.是否有可能这样做,因为我想使用该语句PreparedStatement在Java中创建?

编辑 这个问题PreparedStatements与Java 无关这是关于我想在创建时作为参数传递的SQL语法PreparedStatement.我不想要任何答案PreparedStatement.

wil*_*ser 9

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

WITH src AS (
        UPDATE serial_rate
        SET rate = 22.53, serial_key = '0002'
        WHERE serial_key = '002' AND id = '01'
        RETURNING *
        )
UPDATE serial_table dst
SET serial_key = src.serial_key
FROM src
-- WHERE dst.id = src.id AND dst.serial_key  = '002'
WHERE dst.id = '01' AND dst.serial_key  = '002'
        ;
Run Code Online (Sandbox Code Playgroud)

  • 这仍然是两个语句,并不是很清楚只是在事务/存储过程中执行两个更新语句,并且作为准备好的语句更难以实现(想想一个长而丑陋的字符串,其中到处都是变量) (2认同)
  • 不,他们被捆绑在一起(相当笨拙).提示:只有一个分号.只需将`EXPLAIN`放在它前面,您就会看到它将为组合更新生成一个查询计划. (2认同)
  • @DanField:不,这只是一个查询。当然,它只有一个查询计划。诀窍是在第一个 UPDATE 命令中结合 CTE 和 RETURNING 的用法,这将在第二个 UPDATE 命令中使用。 (2认同)

Bli*_*lip 5

这是a_horse_with_no_name在 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)
    ;
Run Code Online (Sandbox Code Playgroud)

这实际上是wildplasser发布的内容的修改版本,作为对我关于该serial_key字段是否可以使用一次的查询的答复。