在表格中插入新的行并自动生成ID编号

3

我想在我的表中插入新行,希望id可以自动生成而不需要由用户提供。用户只需提供标题和文本。我用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");
?>

很遗憾,在我的网站上测试时,我收到了以下错误信息:

错误:主键为“PRIMARY”的条目'0'重复

mysql_insert_id()无效?出了什么问题?


除非在当前会话/连接中进行插入操作,否则您将无法获得有效的mysql_insert_id()。解决方法:在表创建脚本中自动增加主键(AUTOINCREMENT)。 - Mouse Food
5个回答

5

不要这样做。mysql会为你创建一个自动递增的列:

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()仅返回由当前连接创建的最后一个id。在第一次运行它时,您还没有插入任何数据,因此什么也不会返回。

您的版本极其容易受到竞争条件的影响。不能保证使用mysql_insert_id()检索到的最后一个ID不会被并行运行的另一个脚本副本检索并从该脚本副本下面获取。


感谢 auto_increment。 - felice

4

公告的主键列应该是自动增量的。当您执行mysql_insert_id()时,它会从该连接执行的最后一个查询中检索id。

由于INSERT是当前正在执行的查询,因此会出现错误。

尝试

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

只需将“date_field”、“title”和“text”替换为相应的列名即可。

或者,以下方法也可以使用,因为自增值中的NULL值应该是可接受的。

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

如其他建议所提到的,你应该确保公告表的主键字段设置为自动递增。

另外,当你想要使用刚插入的行的ID时,可以使用mysql_insert_id()方法,例如如果你想要选择刚插入的行,则可以执行以下操作:

'SELECT * FROM announcements WHERE id = '.mysql_insert_id()

2
假设您的表已正确设置,其中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。(也就是说,它给你的是上一次插入的值,而不是下一次插入的值。)

2
问题在于你正在请求最后插入的ID,而你没有插入任何内容。
  1. 如果数据库中的ID字段不是自增长的,请将其转换成自增长。
  2. 将你的公告插入到数据库中
  3. 然后使用mysql_insert_id来获取id。

但是我看到你只有在插入时才会使用它,因此你不需要那个功能。只需像这样插入即可,无需ID:

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

当使用来自$_POST或$_GET或任何其他用户输入的值时,您应该非常小心地处理查询。存在通过表单字段执行SQL注入的可能性,因此建议您使用mysql转义命令或使用参数。

希望这可以帮到您。


我试图将我的id字段转换为自动递增,但是我收到了这个错误信息:#1062-ALTER TABLE导致自动递增重新排序,导致'PRIMARY'键的重复条目'1'。 - felice
从表中删除您的ID字段,然后使用auto_increment选项将其添加回去。这个错误是因为该表中已经有记录了。但请确保您没有在其他地方使用已经存在的ID。 - Senad Meškin

2
您可能希望在创建表时添加“自动递增”选项。 这将在插入数据时自动添加ID。
例如:
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列的ID" - http://php.net/manual/en/function.mysql-insert-id.php


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接