2013-06-13 2 views
4

У меня есть инструкция, которая пытается вставить запись, и если она уже существует, она просто обновляет запись.Получение количества строк вставки/обновления из ON DUPLICATE KEY UPDATE

INSERT INTO temptable (col1,col2,col3) 
VALUES (1,2,3) 
ON DUPLICATE KEY UPDATE col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3); 

Полное утверждение имеет несколько вставок, и я ищу, чтобы подсчитать количество закладных против Updates. Могу ли я сделать это с помощью переменных MySQL, мне еще предстоит найти способ сделать это после поиска.

+0

Я не думаю, что ваш примерный запрос фактически обновит что-нибудь, только вставьте, поскольку не представляется первичным ключом, который вы не обновляете в предложении 'ON DUPLICATE KEY'. Это в основном становится простым INSERT, если вы делаете это, как в примере. –

+0

IMHO вы должны использовать спусковой крючок ON INSERT. –

+0

Я удалил код для примера, но полный оператор будет либо вставлять, либо обновлять. Мне просто интересно, как я могу подсчитать вставки и обновления для отображения пользователю –

ответ

3

От Mysql Docs

В случае "INSERT ... ON дубликатом ключа UPDATE" запросов, возвращаемое значение будет равно 1, если вставка была выполнена, или 2 для обновления существующей строки.

Используйте mysql_affected_rows() после вашего запроса, если INSERT была выполнена, это даст вам 1 и если UPDATE выполняли это даст вам 2.

+0

Если запись не является точным дубликатом: 'значение затронутых строк для каждой строки равно 1, если строка вставлена ​​как новая строка, 2, если существующая строка обновлена, и 0, если существующая строка установлена ​​на ее текущие значения ' –

+0

Но что происходит, когда вы вставляете 2 или более записей одновременно, скажем, что тот, который заканчивается, вставлен, а другой, который заканчивается обновлением ??? – gunslingor

0

Если вы хотите получить количество записей, которые были вставлены и обновлены отдельно, вы должны выдать каждое утверждение отдельно.

+1

уточните, пожалуйста, что вы пытаетесь сказать –

+1

ok лучший пример: INSERT INTO temptable (col1, col2, col3) ЦЕННОСТИ (1,2,3), (3,2,1), (4, 5,6) ON DUPLICATE KEY UPDATE col1 = VALUES (col1), col2 = VALUES (col2), col3 = VALUES (col3); –

0

Вы можете использовать mysql_affected_rows() сразу после вашего запроса.

http://dev.mysql.com/doc/refman/5.1/en/mysql-affected-rows.html

+0

Боюсь, что этого не хватает. Вопрос заключается в том, как интерпретировать затронутые строки таким образом, чтобы отличать вставки от обновлений. – mafu

1

Я знаю, что это немного устарело, но я делал массовую вставку на PHP и мне нужно было точно знать, сколько строк было вставлено и обновлено (отдельно).

Так что я использовал это:

$dataCount = count($arrData); // number of rows in the statement 
$affected = mysql_affected_rows(); // mysqli_*, PDO's rowCount() or anything 

$updated = $affected - $dataCount; 
$inserted = 2 * $dataCount - $affected; 

Простой след таблицы:

------------------------------- 
| data | affected | ins | upd | 
------------------------------- 
| 1 |  1 | 1 | 0 | 
------------------------------- 
| 2 |  2 | 2 | 0 | 
| 2 |  3 | 1 | 1 | 
| 2 |  4 | 0 | 2 | 
------------------------------- 
| 3 |  3 | 3 | 0 | 
| 3 |  4 | 2 | 1 | 
| 3 |  5 | 1 | 2 | 
| 3 |  6 | 0 | 3 | 
------------------------------- 
| 4 |  4 | 4 | 0 | 
| 4 |  5 | 3 | 1 | 
| 4 |  6 | 2 | 2 | 
| 4 |  7 | 1 | 3 | 
| 4 |  8 | 0 | 4 | 
------------------------------- 
| 5 |  5 | 5 | 0 | 
| 5 |  6 | 4 | 1 | 
| 5 |  7 | 3 | 2 | 
| 5 |  8 | 2 | 3 | 
| 5 |  9 | 1 | 4 | 
| 5 |  10 | 0 | 5 | 
------------------------------- 
+0

Что? Я не понимаю. Если данные есть, скажем, 3 и затронутые возвраты как 3. Как вы знаете, если его 1 ins + 1 upd или 3 ins + 0 upd? Оба из них приведут к 3 ... – Clox

+0

Привет! Посмотрите на стол, который я разместил. Если вы вставляете 3 строки и 'mysql_affected_rows()' возвращается 3, это не будет 1 ins и 1 upd, потому что это всего лишь 2 строки, правильно? : D – vcampitelli

0

Я выполнил то, что вы описываете, используя время цикла, так что каждая итерация создает заявление MySQL, который влияет один ряд. Внутри цикла я запускаю mysql_affected_rows(), а затем увеличиваю счетчик в зависимости от того, было ли возвращаемое значение равным 0 или 1. В конце цикла я повторяю обе переменные для просмотра.

Полная формулировка от MySQL Docs относительно функции mysql_affected_rows есть (уведомление есть 3 возможных значения, возвращаемые - 0, 1 или 2):

Для INSERT ... ON дубликатом ключа заявления UPDATE, пораженный -rows Значение в строке равно 1, если строка вставлена ​​как новая строка, 2 если обновленная существующая строка обновлена ​​и 0, если существующая строка установлена ​​в ее текущие значения . Если вы укажете флаг CLIENT_FOUND_ROWS, значение поврежденных строк равно 1 (не 0), если существующая строка установлена ​​в ее текущие значения .

(Sidenote - Я поставил $ countUpdate и $ countInsert и $ countUpdateNoChange до 0 до времени цикла):

Вот код, который я разработал, что работает для меня:

while (conditions...) {  
$sql = "INSERT INTO test_table (control_number, name) VALUES ('123', 'Bob') 
    ON DUPLICATE KEY UPDATE name = 'Bob'"; 

    mysql_query($sql) OR die('Error: '. mysql_error()); 

    $recordModType = mysql_affected_rows(); 

    if ($recordModType == 0) { 
     $countUpdateNoChange++; 
    }elseif($recordModType == 1){ 
     $countInsert++; 
    }elseif($recordModType == 2){ 
     $countUpdate++; 
    }; 
}; 

echo $countInsert." rows inserted<br>"; 
echo $countUpdateNoChange." rows updated but no data affected<br>"; 
echo $countUpdate." rows updated with new data<br><br>"; 

Надеюсь, я не сделал никаких опечаток, поскольку я воссоздал его для совместного использования, удаляя мои конфиденциальные данные.

Надеюсь, это поможет кому-то. Удачи!

Смежные вопросы