2011-07-22 108 views
1

我對ON DUPLICATE KEY UPDATE的功能有點困惑。我正在查找的內容是將檢查INSERT INTO SQL命令,如果有任何行是重複的,請不要更新該行。現在,如果該行中的任何內容不是重複的(但有一些是),我想用更新後的信息替換該行。MYSQL ON DUPLICATE KEY UPDATE問題

這是可能的使用基本的MYSQL,或者我將不得不先拉出所有的數據,然後交叉檢查它。我寧願不這樣做,因爲我所要做的就是每天緩存大量數據。

"INSERT INTO years (date,year,venue,city,state,country,showid) VALUES (?,?,?,?,?,?,?)"

回答

3

ON DUPLICATE KEY UPDATE簡單地執行SET聲明您提供給它一個重複鍵的情況。它不會比較各個列的值,只會更新不同的值。它聽起來像是它可以用於你想要做的事情,只要你有適當的列定義爲UNIQUE KEYPRIMARY KEY

但是,我通常所做的就是運行插入,然後捕獲錯誤並在需要時執行不同的操作。如果存在重複,那麼發出2個查詢會出現問題,但在我看來它更易於維護。

例子:

$db = new PDO($dsn, $user, $pass); 
$stmt = $db->prepare('INSERT INTO some_tbl (col1,col2,col3) VALUES (?,?,?)'); 
$values = array('Col 1 value','Col 2 Value', 'Col 3 Value'); 
try { 
    $db->execute($values); 
} catch (PDOException $e) { 
    if($e->getCode() == 23000){ 
    // dupe key do some other action whether update or otherwise 
    } else { 
    // rethrow non dupe errors 
    throw $e; 
    } 
} 
0

您可以創建您的數據的每一列的唯一索引。如果新行的所有列都是現有行中所有列的完全相同的副本,則這將使其發生重複錯誤,這正是您想要的。

ALTER TABLE TABLE ADD UNIQUE uniqueconstraintname(col1,col2,...);

W3Schools的上唯一約束:http://www.w3schools.com/sql/sql_unique.asp

+0

你能否提供更多的見解?另外我如何捕捉錯誤?我將我的列添加到原始帖子。 – switz

+0

編輯: 如果你這樣設置你的表,然後用INSERT IGNORE INTO運行你的INSERT語句...那麼你的問題就解決了。插入IGNORE將忽略重複值(不插入),因爲它們錯誤並繼續與其他插入。 –

0

the official docs

如果你指定ON DUPLICATE KEY UPDATE,並且插入一行是 會在唯一索引或主鍵導致重複值, 執行舊行的更新。 例如,如果列中的被聲明爲UNIQUE和包含值 1,下列兩個語句具有相同的效果:

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

UPDATE表SET C = C + 1其中a = 1;

+0

這是什麼意思'在獨特的索引'。我知道主鍵是第一個值,但我想檢查所有的值,而不僅僅是第一個值。 – switz

+0

主鍵不一定是第一個值......它定義爲主鍵。我想你應該看看['CREATE'語句](http://dev.mysql.com/doc/refman/5.0/en/create-table.html)的手冊,然後你可以比較'SHOW CREATE TABLE your_table_name'到那裏,看看發生了什麼。 – prodigitalson

0

我之前誤解了你的問題,我編輯這個職位

你必須爲你正在嘗試做的2米不同的東西將其分離成一個INSERT語句和UPDATE語句。並且爲了使UPDATE語句正常工作,您至少需要一個密鑰,然後檢查該行以查看是否有任何值不同。

您可以檢查行的存在並只在不存在這樣的情況下插入。

INSERT語句

INSERT INTO tbl_name (key, col1, col2, col3) 
SELECT keyval, val1, val2, val3 
FROM dual 
WHERE NOT EXISTS 
(SELECT key, col1, col2, col3 
FROM tbl_name 
WHERE key = keyval AND col1 = val1 AND col2 = val2 AND col3 = val2) 

雙只是一個佔位符表,讓你插入你所希望的任何值,並允許一個WHERE子句

UPDATE語句

UPDATE tbl_name 
SET col1 = val1 
    col2 = val2 
    col3 = val3 
WHERE key = keyval AND 
(col1 <> val1 OR col2 <> val2 OR col3 <> val3) 
1

由於有些人已經建議,你需要做的第一件事是確定什麼是重複行。這是通過設置UNIQUE索引完成的。例如,如果您認爲表格中不存在重複的場地,您可以在場地上設置一個UNIQUE索引。如果它是場地和日期的組合(基本上說 - 你不能在同一天的同一地點舉辦兩場比賽),那麼你可以定義一個組合UNIQUE索引,看起來像UNIQUE(場地,日期)。

當你有這樣的設置。您可以開始使用ON DUPLICATE KEY UPDATE:如果您輸入的數據將與現有的複合唯一鍵相匹配 - 您只會更新相關的列。如果沒有 - 您將添加一個新的。此語句的語法爲:

INSERT INTO table (col1, col2, col3) VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE SET col3 = VALUE(col3); 

這將插入新行,如果有這樣的沒有唯一鍵之前,(讓我們說的唯一關鍵是UNIQUE(COL1,COL2) - 所以沒有對COL1的和col2之前)。如果表格中存在一對col1和col2,它將用您提供的值替換col3值。

現在,就您的示例而言,它看起來像您需要所有列上的複合UNIQUE索引。我不是專家,但對我來說並不像最好的做法:)

因此,我建議重新考慮你的表結構有點:

  • 有一個場地表,其中列像「州,市,地點,場所ID」。這張表可能有一個獨特的索引(州,地點,城市)。
  • 有一個「主」表,其中有「show_id,artist_id,venue_id,time ..」等列。該表然後將具有複合UNIQUE索引(show_id,venue_id)。
  • 有一個藝術家表,其中有一些像「artist_id,artist_name等*」的列。
  • 所有三個表都會在相應的ID上顯示PRIMARY鍵(基本上是UNIQUE和INDEX鍵):show_id,venue_id,artist_id。
相關問題