2012-02-16 78 views
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"); 
?> 

可悲的是,当我测试它在我的网站,我得到这个错误:

Error: Duplicate entry '0' for key 'PRIMARY'

mysql_insert_id()不工作?哪里不对?

+0

你不会有一个有效的mysql_insert_id(),直到你在当前会话/连接的插件。解决方法:AUTOINCREMENT pk(在表创建脚本中)。 – 2012-02-16 20:57:44

回答

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或任何其它用户类型值值时,你应该小心你的查询。有可能通过你的表单字段执行SQLInjection,所以我建议你使用mysql escape命令或使用参数。

我希望这会有所帮助。

+0

我想我的ID字段自动增量转换,但我得到这个回:#1062 - ALTER TABLE导致AUTO_INCREMENT重测序,从而导致重复条目“1”键“PRIMARY” – felice 2012-02-16 21:04:12

+0

删除表格提交您的ID,不是再次添加它用auto_increment选项。此错误是因为您已经在该表中记录。但请确保您没有在其他地方使用已有的ID。 – 2012-02-16 21:08:34

+0

非常感谢你,它现在完美! :) – felice 2012-02-16 21:13:18

5

不要这样做。 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()只返回当前连接创建的最后一个ID。您第一次运行时尚未插入任何数据,因此您什么都得不到。

您的版本非常容易受到竞争条件的影响。不能保证你使用mysql_insert_id()检索到的最后一个ID不会被另一个并行运行的脚本副本检索到,并且可以从这个脚本副本中被狙击出来。

+0

感谢上帝的auto_increment。 – felice 2012-02-16 21:14:13

4

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

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

尝试

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

只需更换 'DATE_FIELD', '标题' 和 '文本' 适用的列名。

或者下面还应该工作,如自动增量值NULL值应该是可以接受

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

正如贴在其他建议中提到,你应该确保该通告表的主键字段被设置为auto_increment。

刚刚完成,你会当你要使用的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。

例如

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