ในบางกรณีการเรียกใช้คำสั่ง UPDATE ในการใช้งานจริงสามารถช่วยประหยัดวันได้ อย่างไรก็ตามการอัปเดต borked อาจแย่กว่าปัญหาเริ่มต้น
ขาดการใช้ฐานข้อมูลทดสอบมีตัวเลือกอะไรบ้างที่จะบอกว่าคำสั่งอัพเดตจะทำอะไรก่อนเรียกใช้
ในบางกรณีการเรียกใช้คำสั่ง UPDATE ในการใช้งานจริงสามารถช่วยประหยัดวันได้ อย่างไรก็ตามการอัปเดต borked อาจแย่กว่าปัญหาเริ่มต้น
ขาดการใช้ฐานข้อมูลทดสอบมีตัวเลือกอะไรบ้างที่จะบอกว่าคำสั่งอัพเดตจะทำอะไรก่อนเรียกใช้
คำตอบ:
นอกเหนือจากการใช้ธุรกรรมตามที่ Imad ได้กล่าวไว้แล้ว (ซึ่งควรจะต้องมีผลต่อไป) คุณยังสามารถตรวจสอบว่าแถวใดได้รับผลกระทบจากการเรียกใช้การเลือกโดยใช้ WHERE clause เดียวกับ UPDATE
ดังนั้นหากคุณอัปเดตเป็น
UPDATE foo
SET bar = 42
WHERE col1 = 1
AND col2 = 'foobar';
ต่อไปนี้จะแสดงให้คุณเห็นว่าแถวใดจะได้รับการอัปเดต:
SELECT *
FROM foo
WHERE col1 = 1
AND col2 = 'foobar';
FOREIGN KEY UPDATE CASCADE
sql ของคุณล้มเหลว
แล้วธุรกรรมล่ะ? พวกเขามีคุณสมบัติ ROLLBACK
@ ดูhttps://dev.mysql.com/doc/refman/5.0/th/commit.html
ตัวอย่างเช่น:
START TRANSACTION;
SELECT * FROM nicetable WHERE somthing=1;
UPDATE nicetable SET nicefield='VALUE' WHERE somthing=1;
SELECT * FROM nicetable WHERE somthing=1; #check
COMMIT;
# or if you want to reset changes
ROLLBACK;
SELECT * FROM nicetable WHERE somthing=1; #should be the old value
โดยทั่วไปบรรทัดเหล่านี้จะไม่ถูกดำเนินการเพียงครั้งเดียว ใน PHP fe คุณจะเขียนอะไรแบบนั้น (อาจจะดูสะอาดกว่าเล็กน้อย แต่ต้องการคำตอบอย่างรวดเร็ว ;-)):
$MysqlConnection->query('START TRANSACTION;');
$erg = $MysqlConnection->query('UPDATE MyGuests SET lastname='Doe' WHERE id=2;');
if($erg)
$MysqlConnection->query('COMMIT;');
else
$MysqlConnection->query('ROLLBACK;');
อีกวิธีหนึ่งคือการใช้ MySQL Variables (ดูhttps://dev.mysql.com/doc/refman/5.7/en/user-variables.htm l และ https://stackoverflow.com/a/18499823/1416909 ):
# do some stuff that should be conditionally rollbacked later on
SET @v1 := UPDATE MyGuests SET lastname='Doe' WHERE id=2;
IF(v1 < 1) THEN
ROLLBACK;
ELSE
COMMIT;
END IF;
แต่ฉันขอแนะนำให้ใช้ตัวตัดภาษาที่มีอยู่ในภาษาโปรแกรมที่คุณชื่นชอบ
ปิด Autocommit ...
MySQL
set autocommit=0;
มันตั้งค่าการคอมมิตอัตโนมัติสำหรับเซสชันปัจจุบัน
คุณดำเนินการตามคำสั่งของคุณดูว่ามีการเปลี่ยนแปลงอะไรบ้างแล้วย้อนกลับหากผิดหรือกระทำหากเป็นไปตามที่คุณคาดไว้!
แก้ไข: ประโยชน์ของการใช้ธุรกรรมแทนการเรียกใช้แบบสอบถามแบบเลือกคือคุณสามารถตรวจสอบชุดผลลัพธ์ได้ง่ายขึ้น
ฉันรู้ว่านี่เป็นการทำซ้ำคำตอบอื่น ๆ แต่ก็มีการสนับสนุนทางอารมณ์บางอย่างที่จะก้าวไปอีกขั้นสำหรับการทดสอบอัปเดต: D
สำหรับการทดสอบการอัปเดตแฮช # คือเพื่อนของคุณ
หากคุณมีคำสั่งอัพเดตเช่น:
UPDATE
wp_history
SET history_by="admin"
WHERE
history_ip LIKE '123%'
คุณแฮชอัปเดตและตั้งค่าสำหรับการทดสอบจากนั้นแฮชกลับใน:
SELECT * FROM
#UPDATE
wp_history
#SET history_by="admin"
WHERE
history_ip LIKE '123%'
มันใช้ได้กับงบง่ายๆ
วิธีแก้ไขเพิ่มเติมที่จำเป็นในทางปฏิบัติคือการรับสำเนา (สำรองข้อมูลซ้ำ) เมื่อใดก็ตามที่ใช้การอัปเดตบนตารางการผลิต phpmyadmin> operation> copy: table_yearmonthday ใช้เวลาเพียงไม่กี่วินาทีสำหรับตาราง <= 100M
ไม่ใช่คำตอบโดยตรง แต่ฉันเคยเห็นสถานการณ์ข้อมูล prod borked มากมายที่สามารถหลีกเลี่ยงได้โดยการพิมพ์WHERE
ประโยคก่อน ! บางครั้งWHERE 1 = 0
สามารถช่วยในการวางคำแถลงการทำงานร่วมกันอย่างปลอดภัยได้เช่นกัน และการดูแผนการดำเนินการโดยประมาณซึ่งจะประมาณแถวที่ได้รับผลกระทบจะเป็นประโยชน์ นอกเหนือจากนั้นในการทำธุรกรรมที่คุณย้อนกลับไปตามที่คนอื่นบอก
WHERE 1 = 0
จะพกพาได้มากกว่าหากใครเจอสิ่งนี้ซึ่งทำงานกับ DBMS อื่น ยกตัวอย่างเช่น SQL Server WHERE FALSE
จะไม่ยอมรับ
ในกรณีเหล่านี้ที่คุณต้องการที่จะทดสอบมันเป็นความคิดที่ดีที่จะมุ่งเน้นเฉพาะในปัจจุบันค่าของคอลัมน์และในเร็ว ๆ นี้เพื่อจะปรับปรุงค่าของคอลัมน์
โปรดดูรหัสต่อไปนี้ที่ฉันเขียนเพื่ออัปเดตราคา WHMCS:
# UPDATE tblinvoiceitems AS ii
SELECT ### JUST
ii.amount AS old_value, ### FOR
h.amount AS new_value ### TESTING
FROM tblinvoiceitems AS ii ### PURPOSES.
JOIN tblhosting AS h ON ii.relid = h.id
JOIN tblinvoices AS i ON ii.invoiceid = i.id
WHERE ii.amount <> h.amount ### Show only updatable rows
# SET ii.amount = h.amount
วิธีนี้ทำให้เราเปรียบเทียบค่าที่มีอยู่แล้วเทียบกับค่าใหม่ได้อย่างชัดเจน
เรียกใช้คิวรีแบบเลือกบนตารางเดียวกันโดยมีwhere
เงื่อนไขทั้งหมดที่คุณใช้ในคิวรีอัพเดต
สร้างSELECT
มันขึ้นมา
เช่นถ้าคุณมี
UPDATE users SET id=0 WHERE name='jan'
แปลงเป็นไฟล์
SELECT * FROM users WHERE name='jan'
อีกทางเลือกหนึ่งคือขอ MySQL สำหรับแผนการสืบค้น สิ่งนี้บอกคุณได้สองอย่าง:
ใน MySQL และฐานข้อมูล SQL ส่วนใหญ่คำสั่งแผนแบบสอบถามคือdescribe
ดังนั้นคุณต้องทำ:
describe update ...;