MySQL ON DUPLICATE KEY UPDATE สำหรับการแทรกหลายแถวในแบบสอบถามเดียว


199

ฉันมีแบบสอบถาม SQL ที่ฉันต้องการแทรกหลายแถวในแบบสอบถามเดียว ดังนั้นฉันจึงใช้สิ่งที่ชอบ:

$sql = "INSERT INTO beautiful (name, age)
  VALUES
  ('Helen', 24),
  ('Katrina', 21),
  ('Samia', 22),
  ('Hui Ling', 25),
  ('Yumie', 29)";

mysql_query( $sql, $conn );

ปัญหาคือเมื่อฉันเรียกใช้แบบสอบถามนี้ฉันต้องการตรวจสอบว่าควรตรวจสอบUNIQUEคีย์ (ซึ่งไม่ใช่PRIMARY KEY) หรือไม่เช่น'name'ด้านบนและถ้ามี'name'อยู่แล้วควรมีการแทรกแถวทั้งหมดที่สอดคล้องกันหรือไม่

ตัวอย่างเช่นในตัวอย่างด้านล่างหาก'Katrina'มีอยู่ในฐานข้อมูลแล้วทั้งแถวโดยไม่คำนึงถึงจำนวนของฟิลด์ควรได้รับการอัปเดต อีกครั้งถ้า'Samia'ไม่มีอยู่แถวควรจะแทรก

ฉันคิดว่าจะใช้:

INSERT INTO beautiful (name, age)
      VALUES
      ('Helen', 24),
      ('Katrina', 21),
      ('Samia', 22),
      ('Hui Ling', 25),
      ('Yumie', 29) ON DUPLICATE KEY UPDATE

นี่คือกับดัก ฉันติดอยู่และสับสนเกี่ยวกับวิธีการดำเนินการ ฉันมีหลายแถวที่จะแทรก / อัปเดตในแต่ละครั้ง กรุณาบอกทิศทางฉัน ขอบคุณ

คำตอบ:


479

ใช้คำสำคัญVALUESเพื่ออ้างอิงค่าใหม่ (ดูเอกสารประกอบ )

INSERT INTO beautiful (name, age)
    VALUES
    ('Helen', 24),
    ('Katrina', 21),
    ('Samia', 22),
    ('Hui Ling', 25),
    ('Yumie', 29)
ON DUPLICATE KEY UPDATE
    age = VALUES(age),
     ...

2
ถ้าหากเราต้องการรวมคำสั่ง IF ใน UPDATE ที่มีเงื่อนไขแตกต่างกันสำหรับแต่ละแถว
ลอจิก

2
@logic: มีหลายคำถามที่เกี่ยวข้องกับการนี้: การค้นหา StackOverflow หากไม่มีพวกเขาตอบคำถามของคุณโปรดโพสต์ใหม่เพื่ออธิบายสิ่งที่คุณต้องการ
Peter Lang

@logic คุณพบวิธีแก้ไขปัญหาของคุณหรือไม่ ขณะนี้ฉันกำลังเผชิญปัญหาเดียวกัน
Parth kharecha

ข้อเสนอแนะที่ดี หากคุณต้องการเพิ่มค่าเมื่อทำซ้ำให้เพิ่มส่วนนี้หลังจากส่วน "ON DUPLICATE KEY UPDATE": total = total + VALUES (total)
phoenix

1

INSERT INTO ... ON DUPLICATE KEY UPDATE จะทำงานเฉพาะกับ MySQL ไม่ใช่สำหรับ SQL Server

สำหรับเซิร์ฟเวอร์ SQL วิธีแก้ไขปัญหานี้คือการประกาศตาราง temp ก่อนใส่ค่าลงในตาราง temp นั้นแล้วใช้ MERGE

แบบนี้:

declare @Source table
(
name varchar(30),
age decimal(23,0)
)

insert into @Source VALUES
('Helen', 24),
('Katrina', 21),
('Samia', 22),
('Hui Ling', 25),
('Yumie', 29);


MERGE beautiful  AS Tg
using  @source as Sc
on tg.namet=sc.name 

when matched then update 
set tg.age=sc.age

when not matched then 
insert (name, age) VALUES
(SC.name, sc.age);

15
ใครใช้เซิร์ฟเวอร์ SQL: D
Jeremy Belolo

-3

คุณสามารถใช้ แทนที่แทน INSERT ... ในวันที่ DUPLICATE KEY UPDATE


28
ใช่ แต่ใช้ REPLACE แถวเก่าจะถูกลบก่อนที่จะแทรกแถวใหม่ ฉันต้องการเก็บแถวเก่าไว้เพื่อรักษารหัสหลัก
Prashant

2
ฉันไม่ทราบว่าการรักษา PK เก่านั้นมีความสำคัญต่อคุณ ... แน่นอนว่า REPLACE จะไม่ทำงานในกรณีนี้ ...
a1ex07

4
PS: "แทนที่เป็น" ต้องใช้สิทธิ์ในการลบและแทรก!
Oliver M Grech

2
และสำหรับเหตุผลด้านลบ / แทรกดังกล่าวข้างต้นก็ยังช้ากว่ามากในกรณีเหล่านี้
Ross

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