2012-05-22 33 views
21

Chúng tôi có một cơ sở dữ liệu được cập nhật hàng ngày vào lúc nửa đêm với cronjob, chúng tôi lấy dữ liệu mới từ một XML bên ngoài.Làm cách nào để biết liệu khi nào sử dụng "cập nhật khóa trùng lặp" một hàng đã được chèn hoặc cập nhật?

Điều chúng tôi làm là chèn tất cả nội dung mới và trong trường hợp có khóa trùng lặp, chúng tôi cập nhật trường đó.

INSERT INTO table (id, col1, col2, col3) 
values (id_value, val1, val2, val3), 
(id_value, val1, val2, val3), 
(id_value, val1, val2, val3), 
(id_value, val1, val2, val3), 
ON DUPLICATE KEY UPDATE 
col1 = VALUES (col1), 
col2 = VALUES (col2), 
col3 = VALUES (col3); 

Điều chúng tôi muốn biết là hàng nào đã được chèn vào thực tế, có nghĩa là chúng tôi muốn có danh sách các mục mới. có bất kỳ truy vấn nào có thể trả về các chèn mới không? Về cơ bản, chúng tôi sẽ cần phải có được tất cả các ID mới và không phải số lượng chèn mới.

Cảm ơn

Trả lời

6

Thêm một cột update_count INT NOT NULL DEFAULT 1 và thay đổi truy vấn của bạn:

INSERT 
INTO table (id, col1, col2, col3) 
VALUES 
(id_value, val1, val2, val3), 
(id_value, val1, val2, val3,), 
(id_value, val1, val2, val3), 
(id_value, val1, val2, val3), 
ON DUPLICATE KEY 
UPDATE 
     col1 = VALUES (col1), 
     col2 = VALUES (col2), 
     col3 = VALUES (col3), 
     update_count = update_count + 1; 

Bạn cũng có thể tăng nó trong một kích hoạt BEFORE UPDATE mà sẽ cho phép bạn để giữ cho các truy vấn như vậy.

+0

Cảm ơn Quassnoi, ý tưởng tuyệt vời, tôi đã sử dụng một cột mới có tên là udpated và áp dụng ý tưởng của bạn với cách tiếp cận khác tôi, xin vui lòng xem lại câu trả lời của bạn cho những sửa đổi tôi đã thực hiện và cho tôi một số phản hồi. Nó làm việc rất tốt nhờ. – multimediaxp

26

Bạn có thể nhận được thông tin này tại thời điểm chèn/cập nhật bằng cách kiểm tra số lượng hàng bị ảnh hưởng trong tập kết quả.

MySQL documentation trạng thái:

Với ON DUPLICATE CẬP NHẬT KEY, bị ảnh hưởng-hàng giá trị mỗi hàng là 1 nếu hàng được chèn vào như một hàng mới và 2 nếu một hàng hiện có được cập nhật.

Bạn cần phải kết hợp ROW_COUNT với LAST_INSERT_ID để nhận câu trả lời và chèn một hàng cùng một lúc.

+1

Điều này giúp xác định * bao nhiêu hàng * được chèn vs cập nhật, nhưng không rõ là mà ... – eggyal

+0

Có chúng tôi nghĩ về nhưng tôi cần biết khóa chính của các hàng được chèn vào, chứ không phải số hoặc số hàng được chèn vào. – multimediaxp

+0

@EddyXP, bạn cần phải kết hợp ROW_COUNT với LAST_INSERT_ID để nhận câu trả lời và chèn một hàng cùng một lúc. –

0

Thêm trường dấu thời gian vào bảng và đặt giá trị mặc định thành current_timestamp nhưng không đặt ON UPDATE CURRENT_TIMESTAMP. Bằng cách đó, nếu bạn biết thời gian công việc cron của bạn chạy, bạn có thể truy vấn tất cả các hàng được thêm vào hoặc sau thời gian đó, nhưng trước khi công việc cron tiếp theo hoặc thời gian kết thúc mà bạn biết chắc chắn cron sẽ hoàn thành .

Alter table your_table add column create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP chỉ nên tự động cập nhật trường create_time cho chèn chứ không phải để cập nhật.

Nếu bạn đọc lên trên MySQL documentation:

Với một khoản DEFAULT nhưng không ON khoản CẬP NHẬT CURRENT_TIMESTAMP, cột có giá trị mặc định cho trước và không được tự động cập nhật để dấu thời gian hiện tại.

Giá trị mặc định tùy thuộc vào mệnh đề DEFAULT quy định CURRENT_TIMESTAMP hoặc giá trị không đổi. Với CURRENT_TIMESTAMP, mặc định là dấu thời gian hiện tại.

Vì vậy, để tổng hợp, truy vấn như SELECT id from your_table where create_timestamp >= $cron_1_time and create_timestamp < $cron_2_time; sẽ cung cấp cho bạn những gì bạn đang tìm kiếm. Tất nhiên, điều này tất cả phụ thuộc vào bạn biết khoảng khi các công việc cron chạy và trong bao lâu.

0

tôi có thể nói thế nào tôi đã làm trong PHP:

1) truy vấn đơn giản SELECT MAX (id) và nhớ nó đến $ max_id từ bảng trước khi Insert Mở trùng lặp.

2) Sau đó, trong quá trình cập nhật, thu thập ID của các hàng bị ảnh hưởng (không có nội dung mới hoặc tồn tại): $ ids [] = mysql_insert_id();

3) Sau đó $ inserted_rows = max ($ ids) - $ max_id;

4) hàng Cập nhật = count ($ ids_srt) - $ inserted_rows

$max_id = mysql_query("SELECT MAX(id) from table"); 
$max_id = mysql_result($max_id, 0); 

// !!! prepare here 'insert on duplicate' query in a cycle 

$result=mysql_query($query); 
$ids[] = mysql_insert_id(); 

// finish inserting and collecting affected ids and close cycle 

$inserted_rows = max($ids)- $max_id; 
$updated_rows = count($ids)- $inserted_rows 
Các vấn đề liên quan