Вставить новую строку в таблицу и автоматически идентифицировать номер - PullRequest
3 голосов
/ 17 февраля 2012

Я хочу вставить новую строку в мою таблицу. Я хочу, чтобы идентификатор генерировался автоматически и не запрашивался у пользователя. Пользователь предоставляет только title и text . Я написал этот код на PHP:

<?php
$hostname = "localhost"; 
$database = "mydb"; 
$username = "myuser"; 
$password = "mypsw";
$link = mysql_connect( $hostname , $username , $password ) or 
        die("Attention! Problem with the connection : " . mysql_error());
if (!$link) 
{
die('Could not connect: ' . mysql_error()); 
}
mysql_query("SET NAMES ‘utf8’",$link);
mysql_select_db("mydb", $link);
$lastid=mysql_insert_id();
$lastid=$lastid+1;
$sql="INSERT INTO announcements VALUES ('$lastid',CURDATE(),'$_POST[title]','$_POST[text]')";
if (!mysql_query($sql,$link)) 
{
die('Error: ' . mysql_error());
}
mysql_close($link);
header("Location: announcement.php");
?>

К сожалению, когда я тестирую его на своем веб-сайте, я получаю эту ошибку:

Ошибка: повторяющаяся запись '0' для ключа 'PRIMARY'

Не работает mysql_insert_id()? Что не так?

Ответы [ 5 ]

5 голосов
/ 17 февраля 2012

Не делай этого. mysql с радостью создаст для вас столбец auto_increment:

CREATE TABLE x (
   id int not null primary key auto_increment
                               ^^^^^^^^^^^^^^---add this to your PK field
);

INSERT INTO x (id) VALUES (null); // creates id = 1
INSERT INTO x (id) VALUES (null); // creates id = 2

mysql_insert_id () возвращает только последний идентификатор, созданный текущим соединением. Вы еще не вставили никаких данных при первом запуске, поэтому вы ничего не получите.

Ваша версия невероятно уязвима к условиям гонки. НЕТ гарантии, что последний идентификатор, полученный с помощью mysql_insert_id (), также не будет получен другой копией скрипта, работающего параллельно, и не будет извлечен из-под этой копии скрипта.

4 голосов
/ 17 февраля 2012

Столбец первичного ключа в объявлениях должен быть auto_increment. Когда вы выполняете mysql_insert_id (), он получает идентификатор из последнего запроса, выполненного из этого соединения.

Поскольку INSERT - это запрос, который вы выполняете в данный момент, он содержит ошибки.

Попробуйте

INSERT INTO announcements 
(date_field, title, text)
VALUES  (CURDATE(),'$_POST[title]','$_POST[text]')

Просто замените поля «date_field», «title» и «text» соответствующими именами столбцов.

В качестве альтернативы также должно работать следующее, так как значение NULL в значении AutoIncrement должно быть приемлемым

INSERT INTO announcements VALUES (NULL,CURDATE(),'$_POST[title]','$_POST[text]')

Как упоминалось в другом опубликованном предложении, вы должны убедиться, что в поле первичного ключа таблицы объявлений установлено значение auto_increment.

Просто для завершения, вы будете использовать mysql_insert_id (), когда хотите использовать идентификатор для только что вставленной строки, то есть, если вы затем хотите выбрать только что вставленную строку, вы могли бы сделать

'SELECT * FROM announcements WHERE id = '.mysql_insert_id()
2 голосов
/ 17 февраля 2012

Возможно, вы захотите добавить «автоинкремент» в таблицу при ее создании.
Это автоматически добавит идентификатор при вставке чего-либо.

, например

CREATE TABLE announcements 
(
  id int NOT NULL AUTO_INCREMENT, 
  PRIMARY KEY(id),
  some_date int(11),
  title varchar(200),
  text varchar(3000) 
);

mysql_insert_id "Извлекает идентификатор, сгенерированный для столбца AUTO_INCREMENT по предыдущему запросу" - http://php.net/manual/en/function.mysql-insert-id.php

2 голосов
/ 17 февраля 2012

Проблема в том, что вы запрашиваете последний идентификатор вставки, и вы ничего не вставили.

  1. Преобразуйте поле идентификатора в db, чтобы оно было автоинкрементным, если его нет.
  2. Вставьте в базу данных ваше объявление
  3. Затем запросите идентификатор, используя mysql_insert_id, чтобы получить его.

Но я вижу, что вы используете его не только при вставке, тогда вам не нужны эти функцииво всяком случае.Просто вставьте без идентификатора, подобного этому

"insert into announcements (InsertDate, Title, Text) VALUES (CURDATE(), '$_POST[title]', '$_POST[text]')";

, и вы действительно должны быть осторожны с вашими запросами при использовании значений из $ _POST или $ _GET или любого другого пользовательского значения.Существует возможность выполнить SQLInjection через поля формы, поэтому я предлагаю вам использовать команду escape mysql или параметры.

Надеюсь, это поможет.

2 голосов
/ 17 февраля 2012

Если ваша таблица настроена правильно, с полем id, равным AUTO_INCREMENT, вам просто нужно выполнить INSERT, где вы не указываете значение для id. Это означает, что вы должны указать имена вставляемых столбцов. Итак, эта строка:

$sql="INSERT INTO announcements VALUES ('$lastid',CURDATE(),'$_POST[title]','$_POST[text]')";

становится этим

$sql="INSERT INTO announcements (`date`,`title`,`text`) VALUES (CURDATE(),'$_POST[title]','$_POST[text]')";

Я догадался, какими могут быть имена ваших столбцов. Очевидно, они должны соответствовать вашему определению таблицы.

Если вы сделаете это, функция mysql_insert_id() вернет id строки, которую вы вставили . (То есть он дает вам значение предыдущей вставки, а не следующей.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...