Php insert into on duplicate key

mysqli_insert_id

Возвращает идентификатор, сгенерированный запросом INSERT или UPDATE для таблицы со столбцом, имеющим атрибут AUTO_INCREMENT . В случае многострочного оператора INSERT он возвращает первое автоматически сгенерированное значение, которое было успешно добавлено.

Выполнение запроса INSERT или UPDATE с использованием MySQL-функции LAST_INSERT_ID() также изменит значение, возвращаемое mysqli_insert_id() . Если LAST_INSERT_ID(expr) использовался для генерации значения AUTO_INCREMENT , он возвращает значение последнего expr вместо сгенерированного значения AUTO_INCREMENT .

Возвращает 0 , если предыдущий оператор не изменил значение AUTO_INCREMENT . mysqli_insert_id() должен вызываться сразу после запроса, сгенерировавшего значение.

Список параметров

Только для процедурного стиля: объект mysqli , полученный с помощью mysqli_connect() или mysqli_init() .

Возвращаемые значения

Значение поля AUTO_INCREMENT , которое было затронуто предыдущим запросом. Возвращает ноль, если предыдущий запрос не затронул таблицы, содержащие поле AUTO_INCREMENT .

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

Замечание:

Если число больше максимального значения целого числа, функция вернёт строку.

Примеры

Пример #1 Пример функции $mysqli->insert_id

mysqli_report ( MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT );
$mysqli = new mysqli ( «localhost» , «my_user» , «my_password» , «world» );

$mysqli -> query ( «CREATE TABLE myCity LIKE City» );

$query = «INSERT INTO myCity VALUES (NULL, ‘Stuttgart’, ‘DEU’, ‘Stuttgart’, 617000)» ;
$mysqli -> query ( $query );

printf ( «ID новой записи: %d.\n» , $mysqli -> insert_id );

/* удаление таблицы */
$mysqli -> query ( «DROP TABLE myCity» );

mysqli_report ( MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT );
$link = mysqli_connect ( «localhost» , «my_user» , «my_password» , «world» );

mysqli_query ( $link , «CREATE TABLE myCity LIKE City» );

$query = «INSERT INTO myCity VALUES (NULL, ‘Stuttgart’, ‘DEU’, ‘Stuttgart’, 617000)» ;
mysqli_query ( $link , $query );

printf ( «ID новой записи: %d.\n» , mysqli_insert_id ( $link ));

/* удаление таблицы */
mysqli_query ( $link , «DROP TABLE myCity» );

Результат выполнения данных примеров:

User Contributed Notes 10 notes

I have received many statements that the insert_id property has a bug because it «works sometimes». Keep in mind that when using the OOP approach, the actual instantiation of the mysqli class will hold the insert_id.

The following code will return nothing.
$mysqli = new mysqli ( ‘host’ , ‘user’ , ‘pass’ , ‘db’ );
if ( $result = $mysqli -> query ( «INSERT INTO t (field) VALUES (‘value’);» )) echo ‘The ID is: ‘ . $result -> insert_id ;
>
?>

This is because the insert_id property doesn’t belong to the result, but rather the actual mysqli class. This would work:

$mysqli = new mysqli ( ‘host’ , ‘user’ , ‘pass’ , ‘db’ );
if ( $result = $mysqli -> query ( «INSERT INTO t (field) VALUES (‘value’);» )) echo ‘The ID is: ‘ . $mysqli -> insert_id ;
>
?>

There has been no examples with prepared statements yet.

«`php
$u_name = «John Doe»;
$u_email = «johndoe@example.com»;

$stmt = $connection->prepare(
«INSERT INTO users (name, email) VALUES (?, ?)»
);
$stmt->bind_param(‘ss’, $u_name, $u_email);
$stmt->execute();

For UPDATE you simply change query string and binding parameters accordingly, the rest stays the same.

Of course the table needs to have AUTOINCREMENT PRIMARY KEY.

When using «INSERT . ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id`)», the AUTO_INCREMENT will increase in an InnoDB table, but not in a MyISAM table.

Watch out for the oo-style use of $db->insert_id. When the insert_id exceeds 2^31 (2147483648) fetching the insert id renders a wrong, too large number. You better use the procedural mysqli_insert_id( $db ) instead.

[EDIT by danbrown AT php DOT net: This is another prime example of the limits of 32-bit signed integers.]

When running extended inserts on a table with an AUTO_INCREMENT field, the value of mysqli_insert_id() will equal the value of the *first* row inserted, not the last, as you might expect.

//mytable has an auto_increment field
$db->query(«INSERT INTO mytable (field1,field2,field3) VALUES (‘val1′,’val2′,’val3’),
(‘val1′,’val2′,’val3’),
(‘val1′,’val2′,’val3’)»);

echo $db->insert_id; //will echo the id of the FIRST row inserted
?>

If you try to INSERT a row using ON DUPLICATE KEY UPDATE, be aware that insert_id will not update if the ON DUPLICATE KEY UPDATE clause was triggered.

When you think about it, it’s actually very logical since ON DUPLICATE KEY UPDATE is an UPDATE statement, and not an INSERT.

In a worst case scenario, if you’re iterating over something and doing INSERTs while relying on insert_id in later code, you could be pointing at the wrong row on iterations where ON DUPLICATE KEY UPDATE is triggered!

What is unclear is how concurrency control affects this function. When you make two successive calls to mysql where the result of the second depends on the first, another user may have done an insert in the meantime.

The documentation is silent on this, so I always determine the value of an auto increment before and after an insert to guard against this.

I was having problems with getting the inserted id, and did a bit of testing. It ended up that if you commit a transaction before getting the last inserted id, it returns 0 every time, but if you get the last inserted id before committing the transaction, you get the correct value.

The example is lack of insert_id in multi_query. Here is my example:
Assuming you have a new test_db in mysql like this:

create database if not exists test_db;
use test_db;
create table user_info (_id serial, name varchar(100) not null);
create table house_info (_id serial, address varchar(100) not null);

Then you run a php file like this:

define ( ‘SERVER’ , ‘127.0.01’ );
define ( ‘MYSQL_USER’ , ‘your_user_name’ );
define ( ‘MYSQL_PASSWORD’ , ‘your_password’ );

$db = new mysqli ( SERVER , MYSQL_USER , MYSQL_PASSWORD , «test_db» , 3306 );
if ( $db -> connect_errno )
echo «create db failed, error is » , $db -> connect_error ;
else $sql = «insert into user_info »
. «(name) values »
. «(‘owen’), (‘john’), (‘lily’)» ;
if (! $result = $db -> query ( $sql ))
echo «insert failed, error: » , $db -> error ;
else
echo «last insert id in query is » , $db -> insert_id , «\n» ;
$sql = «insert into user_info»
. «(name) values »
. «(‘jim’);» ;
$sql .= «insert into house_info »
. «(address) values »
. «(‘shenyang’)» ;
if (! $db -> multi_query ( $sql ))
echo «insert failed in multi_query, error: » , $db -> error ;
else echo «last insert id in first multi_query is » , $db -> insert_id , «\n» ;
if ( $db -> more_results () && $db -> next_result ())
echo «last insert id in second multi_query is » , $db -> insert_id , «\n» ;
else
echo «insert failed in multi_query, second query error is » , $db -> error ;
>
$db -> close ();
>
?>

You will get output like this:

last insert id in query is 1
last insert id in first multi_query is 4
last insert id in second multi_query is 1

Conclusion:
1 insert_id works in multi_query
2 insert_id is the first id mysql has used if you have insert multi values

msqli_insert_id();
This seems to return that last id entered.
BUT, if you have multiple users running the same code, depending on the server or processor I have seen it return the wrong id.

Test Case:
Two users added an item to their list.
I have had a few times where the id was the id from the other user.
This is very very rare and it only happens on my test server and not my main server.

I am guessing it is because of multicores (maybe hyperthreading) or how the operating system handles multi-threads.

It is rare, but it happens.

Источник

Простые советы в примерах по PHP, MySQL, HTML, CSS, JS и LINUX

Простые советы разработки сайтов и приложений. Вы найдете ответы на вопросы, которые нельзя найти где-то ещё.

INSERT . ON DUPLICATE KEY UPDATE или Как вставить строку если она не существует и обновить в противном случае (MySQL)

  • Получить ссылку
  • Facebook
  • Twitter
  • Pinterest
  • Электронная почта
  • Другие приложения

Добрый день ) Уважаемые программисты, наверняка каждый из Вас сталкивался с проблемой вставки данных в БД, если строки не существует и обновление ее, если таковая уже есть.

Как вставить данные в базу данных MySQL, если их не существует и обновить в противном случае

Наверняка Вы часто использовали конструкцию типа:

$result = mysql_query ( «SELECT `uid`, `text` FROM `t_userinfo` WHERE `uid`='». $uid .»‘» );
if ( mysql_num_rows ( $result ) >0 ) < // Если строка имеется, то обновляем
mysql_query ( «UPDATE `t_userinfo` SET `text`='». $newtext .»‘ WHERE `uid`='». $uid .»‘» ) ;
> else < // Если строки нет, то добавляем новое значение в БД
mysql_query ( «INSERT INTO `t_userinfo` SET `text`='». $newtext .»‘,`uid`='». $uid .»‘» ) ;
>

Немного муторно, не правда ли? И производительность немного страдает, все таки столько действий.

Допустим, что эта таблица имеет PRIMARY KEY или UNIQUE, в данном случае это поле uid. То есть таблица должна иметь уникальный ключ.

Вставить или обновить данные в базе данных MySQL одним запросом

И все вышеперечисленные действия можно легко заменить:

mysql_query ( «INSERT INTO `t_userinfo` SET `text`='». $newtext .»‘,`uid`='». $uid .»‘ ON DUPLICATE KEY UPDATE `text`='». $newtext .»‘ » ) ;

Сам MySQL код:

INSERT INTO `t_userinfo` SET `text`=’some_text ‘,`uid`=’some_uid ‘ ON DUPLICATE KEY UPDATE `text`=’some_text ‘;

Пожалуйста пользуйтесь, если строка существует то просто обновить, а если нет — то вставить новое значение (insert, update)

mysql, php, insert. update, on duplicate key update, уникальный ключ, вставить, обновить

  • Получить ссылку
  • Facebook
  • Twitter
  • Pinterest
  • Электронная почта
  • Другие приложения

Комментарии

Отправить комментарий

Популярные сообщения из этого блога

Как преобразовать строку в массив в ClickHouse / How to transform string to array in ClickHouse

Сегодня я столкнулся с проблемой, что в документации ClickHouse нет функции преобразования строки в массив. Поискав в StackOverflow , я тоже ничего внятно не нашел. Попробую объяснить на примере: У вас есть некая колонка data типа String, которая хранит JSON: <"user_id":123456,"item_ids": [1203,1204,1205] ,"count":5>Вы хотите преобразовать поле item_ids в массив, чтобы в дальнейшем с ним производить любые функции по работе с массивами ( ссылка на документацию в конце поста ). Как преобразовать строку в массив из JSON Строка может содержать не в отдельной колонке, а, например, в поле json. Пример ниже продемонстрирует как этого добиться: С помощью функции visitParamExtractRaw достать значение поля item_ids в сыром виде: visitParamExtractRaw( data , ‘item_ids’ ) С помощью функции trim убрать лишние квадратные скобки по краям: trim ( BOTH ‘[]’ FROM visitParamExtractRaw( data , ‘reward_ids’ )) p.s. Можно также убрать и фигур

Как разложить массив на несколько строк в ClickHouse

Изображение

Иногда возникает ситуация, когда нужно разложить поле, содержащее столбец-массив на несколько строк, то есть вынести в столбец каждый отдельный элемент массива. Другими словами: как разгруппировать колонку в несколько строк. Например, разложить колонку room_number на несколько строк. В примере ниже мы разложили колонку room_number на несколько строк для consumer_id = 1694953573. Получаем следующий результат: Как видим из примера выше, каждый элемент массива room_numbers теперь на отдельной строке. Делается это при помощи конструкции ARRAY JOIN. Синтаксис следующий: [ LEFT ] ARRAY JOIN < array >Вместо вы должны указать колонку или выражение, которое возвращает массив. Для нашего примера запрос будет таким: SELECT consumer_id, room_number, order_date FROM orders ARRAY JOIN room_numbers as room_number WHERE consumer_id = 1694953573; Profit! Приветствуются конструктивные комментарии. Спасибо. P.S. А если поле у вас не массив, а строка, т

Экспорт одной таблицы базы данных или mysqldump одной таблицы (MySQL)

Как экспортировать одну таблицу из базы данных MySQL, используя mysqldump Например, Вам нужно произвести экспорт всего одной таблицы из всей базы данных MySQL, существует довольно простая утилита mysqldump . Синтаксис довольно прост: mysqldump —user= [имя пользователя] —host= [имя хоста или ip-адрес] —password= [пароль] [имя базы данных] [имя таблицы] > имя-файла.sql Например: mysqldump —user-root —host=127.0.0.1 —pasword=mypassword mydbname table1 > report1.sql Вот и все, все оказалось просто. Весь дамп текущей таблицы, будет находиться в файле: report1.sql Экспорт структуры таблицы MySQL Если Вам нужно экспортировать только структуру таблицы базы данных, а сами данные не нужны, то нужно просто добавить флаг —no-data . Вот пример: mysqldump —user-root —host=127.0.0.1 —pasword=mypassword —no-data mydbname table1 > report2.sql Теперь в файле report2.sql будет только структура таблицы table1. Экспорт нескольких таблиц базы дан

Источник

Читайте также:  Команды в питоне int input
Оцените статью