2015-04-27 65 views
2

我有2個表如下:PostgreSQL的更新多個表

  1. serial_table

    id CHARACTER VARYING(20), 
    serial_key CHARACTER VARYING(20), 
    PRIMARY KEY(id, serial_key) 
    
  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) 
    

現在我想更新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'); 

我知道這是不正確的。 有沒有可能的方法來做到這一點,因爲我想用這個語句在Java中創建一個PreparedStatement

編輯 這個問題是不是在Java中約PreparedStatements它是關於SQL語法,我希望傳遞的參數創建一個PreparedStatement我不想要任何關於PreparedStatement的答案。

+0

你真的打算更新一個PK組件的'serial_table.serial_key'嗎?並且:應該更新serial_rate.serial_key(也是一個PK組件,而FK是第一個)?否則:FK約束可能被違反。 – wildplasser

+0

@wildplasser第一個答案是肯定的,至於第二部分,FK是ON UPDATE CASCADE ON DELETE RESTRICT。 – Blip

+0

可能重複[爲多個表Java創建一個preparedstatement](http://stackoverflow.com/questions/15276124/one-preparedstatement-for-multiple-tables-java) –

回答

5

這是一個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' 
     ; 
+0

這仍然是兩個語句,它不是很明顯只是在一個事務/存儲過程中做兩個更新語句,並且作爲一個準備好的語句將更加難以實現(想想一個遍佈各處變量的長長的字符串) –

+2

否,他們被鏈接在一起(相當笨拙)。提示:只有一個分號。只要將'EXPLAIN'放在它的前面,就會發現它會導致組合更新的一個查詢計劃。 – wildplasser

+0

這實際上是一個子查詢,雖然正確嗎?這是兩個查詢與一個查詢計劃? –

1

這正是被張貼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) 
    ; 

這實際上是什麼被張貼wildplasser爲我的查詢答覆是否serial_key字段可以使用一次的修改版本。