2012-03-02 28 views
55

Tôi biết rằng bạn có thể sử dụng ON DUPLICATE KEY UPDATE để cập nhật một giá trị nhất định nếu có một kỷ lục cho khóa đó rồi,Có cách nào để sử dụng ON KHÓA KHÓA để cập nhật tất cả những gì tôi muốn chèn?

tôi có thể làm điều này:

INSERT INTO `tableName` (`a`,`b`,`c`) VALUES (1, 2, 3) 
ON DUPLICATE KEY UPDATE `a`=1, `b`=2, `c`=3 

Nhưng làm thế nào tôi có thể làm điều này mà không cần phải viết ra các cột và giá trị hai lần?

+0

http://stackoverflow.com/questions/294661/what-is-the-best-way-to-insert-in-and-update-a-đơn-row-table-in-mysql –

Trả lời

70

Unfortunately not.

Bạn có thể nhận được một nửa chiều có bằng cách không phải lặp lại các giá trị:

INSERT INTO `tableName` (`a`,`b`,`c`) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE `a`=VALUES(`a`), `b`=VALUES(`b`), `c`=VALUES(`c`); 

Nhưng bạn vẫn phải liệt kê các cột.

+0

@Neal: Giá trị của bạn để chèn là phức tạp, tôi mang nó? –

+0

:-(http://chat.stackoverflow.com/transcript/message/2819869#2819869 – Neal

+0

Nó dường như không hoạt động ^^^ – Neal

28

sử dụng REPLACE INTO

Ý nghĩa của REPLACE INTO là NẾU kỷ lục mới trình bày giá trị khóa mới, sau đó nó sẽ được chèn vào như một lần nữa kỷ lục.

Nếu bản ghi mới có giá trị khóa khớp với bản ghi đã tồn tại trước đó, thì vi phạm chính sẽ bị bỏ qua và bản ghi mới sẽ thay thế bản ghi đã có trước đó.

+5

Ah, điều đó có thể tốt hơn nhiều. Đáng chú ý là tất cả các trường không được cho rõ ràng trong truy vấn sẽ được mặc định, tuy nhiên, điều này rõ ràng khác với hành vi 'ON DUPLICATE KEY UPDATE'. –

+40

Lưu ý: với 'REPLACE', nếu khóa của bản ghi khớp với thứ đã tồn tại, ** hàng cũ (s!) Sẽ bị xóa và nút mới được chèn **.Điều này có thể là một vấn đề lớn nếu bạn gây rối với các yếu tố kích hoạt hoặc các ràng buộc khóa ngoại. – cHao

+2

Điểm tốt. Bạn đang mạo hiểm một số phản ứng dây chuyền đáng kể, tôi đoán vậy. –

6

Nếu nó rất hữu ích, tôi đã thực hiện một truy vấn để tránh phải viết bằng tay phần cuối cùng của "trên trùng lặp" truy vấn, cho các phiên bản> = 5.0:

SELECT GROUP_CONCAT(CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'database_name' AND TABLE_NAME = 'table_name'; 

và đầu ra của nó là thế này:

a=values(a), b=values(b), c=values(c), d=values(d) 

trên một bảng có các cột a, b, c và d, vì vậy bạn có thể thêm vào phần đầu tiên của truy vấn:

INSERT INTO `tableName` (`a`,`b`,`c`, `d`) VALUES (1,2,3,4) ON DUPLICATE KEY UPDATE a=values(a), b=values(b), c=values(c), d=values(d) 

UPDATE: Đối với một danh sách rất dài các cột bạn có thể thấy sản lượng cắt ngắn, bạn có thể sử dụng báo cáo này trước khi truy vấn trên (nhờ Uncle iroh):

SET SESSION group_concat_max_len = 1000000; 
+1

Tình yêu này. Đôi khi tôi cần điều này trước khi truy vấn rất hữu ích của bạn. SET SESSION group_concat_max_len = 1000000; –

Các vấn đề liên quan