2010-03-18 5 views
32

Tôi đang thực hiện INSERT ... ON DUPLICATE KEY UPDATE nhưng tôi cần phần cập nhật để có điều kiện, chỉ thực hiện cập nhật nếu một số điều kiện bổ sung đã thay đổi.CHERTN ... VỀ CẬP NHẬT KHÓA CHÍNH XÁC VỚI ĐÂU?

Tuy nhiên, WHERE không được phép trên UPDATE này. Có cách giải quyết nào cho vấn đề này không?

Tôi không thể kết hợp INSERT/UPDATE/SELECT vì điều này cần phải làm việc trên một bản sao.

Trả lời

46

Tôi đề nghị bạn sử dụng hàm IF() để thực hiện điều đó.

Tham khảo: conditional-duplicate-key-updates-with-mysql

INSERT INTO daily_events (created_on, last_event_id, last_event_created_at) 
    VALUES ('2010-01-19', 23, '2010-01-19 10:23:11') 
ON DUPLICATE KEY UPDATE 
    last_event_id = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_id), last_event_id); 
+1

Tôi không bao giờ biết tôi có thể truy cập giá trị bảng ban đầu bên trong phần UPDATE. Điều này có thể giải quyết vấn đề của tôi (mặc dù công việc cũ của tôi xung quanh là khá tốt :)) –

+1

Nó có thể xảy ra rằng MySQL sẽ phàn nàn về 'cột trong danh sách lĩnh vực là mơ hồ' - sau đó bạn cần phải sử dụng: 'ON TUYÊN BỐ TĂNG KHÓA CHÍNH daily_events.last_event_id = IF (daily_events.last_event_created_at boryn

+0

Liên kết được đăng lên thewebfellas.com đã chết, thật đáng buồn. –

3

bạn có thể sử dụng hai câu lệnh chèn .. vì bạn CÓ thể thêm mệnh đề where vào phần chọn cho dữ liệu nguồn.

chọn hai bộ dữ liệu, một bộ dữ liệu mà bạn sẽ chèn với 'trùng lặp' và phần còn lại sẽ được chèn mà không có 'trùng lặp'.

10

Đây là giải pháp cuối cùng của chúng tôi, hoạt động như một sự quyến rũ! Và chỉ một lựa chọn.

mysql> desc test; 
+-------+--------------+------+-----+-------------------+-------+ 
| Field | Type   | Null | Key | Default   | Extra | 
+-------+--------------+------+-----+-------------------+-------+ 
| id | int(11)  | NO | PRI | NULL    |  | 
| value | varchar(255) | YES |  | NULL    |  | 
| ts | timestamp | NO |  | CURRENT_TIMESTAMP |  | 
+-------+--------------+------+-----+-------------------+-------+ 

mysql> insert ignore into test values (4, "foo", now()); 
Query OK, 1 row affected (0.01 sec) 

mysql> insert into test select id, "foo", now() from test where id = 4 and ts < now() on duplicate key update value = values(value), ts = values(ts); 
Query OK, 2 rows affected (0.00 sec) 
Records: 1 Duplicates: 1 Warnings: 0 
+1

Ông có thể giải thích như thế nào nó hoạt động? – CMCDragonkai

+0

Giải thích nằm trong câu trả lời @lexu: hai câu lệnh, đầu tiên là 'insert ignore', câu lệnh thứ hai giống như' update ignore'. – xmedeko

+0

Có vẻ như câu lệnh thứ hai chỉ là 'update test set value =" foo ", ts = now() trong đó id = 4 và ts antak

0

bảng php_lock:
name: idString, locked: bool, time: timestamp, locked_by: string
giá trị để chèn hoặc cập nhật
1, CURRENT_TIMESTAMP, 'kịch bản '
trong đó name =' wwww 'AND locked = 2

INSERT INTO `php_lock` (`name`, locked, `time`, `locked_by`) 
(SELECT * FROM 
    (SELECT `name`,1,CURRENT_TIMESTAMP, 'script' FROM `php_lock` 
     WHERE `name`='wwww' AND `locked`=2 
    UNION (
    SELECT 'wwww',1 ,CURRENT_TIMESTAMP, 'script') 
) AS temp LIMIT 1) 
ON DUPLICATE KEY UPDATE locked=VALUES(locked), `time`=VALUES(`time`), `locked_by`=VALUES(`locked_by`); 
-1

On duplicate key không cho phép chúng ta sử dụng mệnh đề where, vì vậy có hai lựa chọn để đạt được như vậy.

  1. Nếu bạn biết hầu hết thời gian bạn sẽ nhận được chìa khóa trùng lặp sau đó

    a. Update the table first using update query and where clause b. If update fails then insert the record into table using insert query

  2. Nếu bạn biết phần lớn thời gian bạn sẽ chèn vào bảng sau đó

    a. Insert the record into table using insert ignore query - what it does is actually ignore the insert if duplicate key found b. If insert ignore fails then update the record using update query

F hoặc tham chiếu của insert ignoreclick here

+1

Làm cách nào để 'bỏ qua bỏ qua' không thành công? –

+0

nếu bạn cố gắng chèn cùng một khóa duy nhất 'chèn bỏ qua' sẽ thất bại. –

+1

Không, đó là những gì 'bỏ qua'. Nó * bỏ qua * ngoại lệ khóa trùng lặp. –

-1
INSERT INTO daily_events 
    (created_on, last_event_id, last_event_created_at) 
VALUES 
    ('2010-01-19', 23, '2010-01-19 10:23:11') 

    ON DUPLICATE KEY UPDATE 

    last_event_id = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_id), last_event_id), 
    last_event_created_at = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_created_at), last_event_created_at); 
+0

Đây không phải là mã từ câu trả lời được chấp nhận? –