อัปเดตคอลัมน์ทั้งหมดจากตารางอื่น


13

ฉันต้องการอัปเดตตารางจากอีกอันหนึ่งและฉันต้องอัปเดตคอลัมน์ทั้งหมด นอกจากการแสดงทุกคอลัมน์ในส่วนSETคำสั่งมีวิธีอัปเดตทั้งหมดในครั้งเดียวหรือไม่ แบบนี้:

update tableA
set * = tableB.*
from tableB where tableA.id = tableB.id

ฉันลอง psql แล้วมันใช้งานไม่ได้ ฉันต้องแสดงรายการทุกคอลัมน์ดังนี้

update tableA
set c1 = tableB.c1, c2 = tableB.c2, ...
from tableB where tableA.id = tableB.id

tableBcreate .. like tableAถูกสร้างขึ้นใช้ ดังนั้นพวกเขาจึงเหมือนกันโดยทั่วไป และเหตุผลที่ฉันทำก็คือว่าผมต้องโหลดข้อมูล CSV เพื่อตาราง temp tableBแล้ว update อยู่บนพื้นฐานของข้อมูลใหม่ในtableA จำเป็นต้องถูกล็อคให้น้อยที่สุดและต้องรักษาความสมบูรณ์ ฉันไม่แน่ใจว่า 'ลบแล้วแทรก' จะเป็นตัวเลือกที่ดีใช่ไหมtableBtableAtableA


1
ฉันทดสอบด้วยโค้ดที่สองของคุณแล้วมันใช้งานได้! คุณควรตรวจสอบสองหัวข้อ: dba.stackexchange.com/questions/58371/… , dba.stackexchange.com/questions/59458/…
Luan Huynh

คำตอบ:


12

นอกจากนี้ไม่มีตัวแปรไวยากรณ์ที่ช่วยให้คุณปรับปรุงแถวทั้งหมดในครั้งเดียว อย่างไรก็ตามมีรูปแบบที่สั้นกว่าสิ่งที่คุณมีจนถึงตอนนี้

นอกจากนี้คุณไม่ต้องการอัปเดตคอลัมน์ทั้งหมด WHEREเงื่อนไขการหมุดรหัสลงอย่างน้อยหนึ่งคอลัมน์ ( id) จะยังคงไม่เปลี่ยนแปลง แต่นั่นเป็นเพียงการวางยา

UPDATE table_a a
SET    (  c1,   c2, ...)
     = (b.c1, b.c2, ...)
FROM   table_b b
WHERE  a.id = b.id;

รายละเอียดเพิ่มเติมในคำตอบที่เกี่ยวข้องนี้:
อัปเดตเป็นกลุ่มของคอลัมน์ทั้งหมด

DELETE / INSERT

ภายในเนื่องจากรุ่น MVCC ของ PostgresทุกคนUPDATEแทรกแถวใหม่ได้อย่างมีประสิทธิภาพอยู่แล้วและทำเครื่องหมายเก่าว่าล้าสมัย ดังนั้นหลังม่านจึงมีความแตกต่างระหว่างUPDATEและDELETEบวกINSERTไม่มาก
มีรายละเอียดบางอย่างในความโปรดปรานของUPDATEเส้นทาง:

  • อัพเดทล่าสุด
  • ตาราง TOAST: หากคุณมีคอลัมน์ขนาดใหญ่เนื้อหาอาจถูกจัดเก็บ "out-of-line" ในตาราง TOAST และเวอร์ชันแถวใหม่สามารถลิงก์ไปยังแถวเดียวกันในตาราง TOAST หากคอลัมน์ toasted ยังคงไม่เปลี่ยนแปลง
  • การบำรุงรักษาดัชนีอาจถูกกว่าสำหรับการอัพเดต

มิฉะนั้นการล็อคควรจะเหมือนกัน คุณต้องล็อคแบบเอกสิทธิ์เฉพาะบุคคลในแถวที่ได้รับผลกระทบด้วยวิธีใดวิธีหนึ่ง เพียงทำให้มันรวดเร็ว
หากคุณกำลังติดต่อกับแถวจำนวนมากและคุณไม่ต้องการสถานะที่สอดคล้องกัน (ทุกแถวหรือไม่มีเลย) คุณสามารถแบ่งการดำเนินการออกเป็นหลายชุด (แยกธุรกรรม!) เพิ่มค่าใช้จ่ายทั้งหมด แต่ทำให้เวลาล็อคต่อแถวสั้นลง


3
DELETE / INSERTนอกจากนี้ยังอาจมีผลกระทบที่ไม่พึงประสงค์หรือแตกต่างกันเพียง UPDATE(น้ำตกหรือเรียกกว่า)
ypercubeᵀᴹ

ถูกต้อง แต่คุณควรอัปเดตชื่อแทนส่วนหนึ่งของ table_a table_a (ซึ่งเป็นตารางที่อัพเดต) ไม่สามารถรับนามแฝงได้
เพียงคนรักรหัสอีก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.