我目前有一个脚本,可以在使用表单添加新元素时自动插入新数据。
我用
public string PDO::lastInsertId ([ string $name = NULL ] )
逻辑当然。现在我只想知道如果表没有ID字段且没有自动增量字段,这是否会导致任何问题。
除此之外,如果这意味着使用了错误的数据库结构。 我想确保这个例程适用于任何情况。好的数据库或糟糕的数据库结构。没关系。
我的意思是我想用数据取回行,以便我可以搜索它。
E.G。
将新数据插入数据库
$query = $pdo->prepare("INSERT INTO `tablename` SET `data_name`='John', `data_familyname`='Doe', 'data_age`=45, `data_wife`='Sarah Doe'");
$query->execute();
完全获取最后插入的行
///$LastID = $pdo->lastInsertId();
$query = $pdo->prepare("SELECT `data_name`,`data_familyname`,`data_age`,`data_wife` FROM `tablename` WHERE LAST IDFIELD = ".$pdo->lastInsertId());
$query->execute();
$row = $query->fetch();
行包含
array(
'data_name' => 'John',
'data_familyname' => 'Doe',
'data_age' => '45',
'data_wife' => 'Sarah Doe'
);
然后使用与刚刚插入的数据完全相同的数据更新最后插入的行
$query = $pdo->prepare("UPDATE `tablename` SET `data_name`='Chris' WHERE `data_name`=? AND `data_familyname`=? AND 'data_age`=? AND `data_wife`=?");
$query->execute(array_values($row));
最后一个查询基本上是:
UPDATE `tablename` SET `data_name`='Chris'
WHERE `data_name`='John' AND `data_familyname`='Doe' AND 'data_age`='45' AND `data_wife`='Sarah Doe'
当然存在重复数据的可能性。而且您只想修改最后一行。如果数据库具有任何良好的结构,那就是我的意思。
但是为了防止重复数据,可以添加:
行包含
array(
'data_id' => 20,
'data_name' => 'John',
'data_familyname' => 'Doe',
'data_age' => '45',
'data_wife' => 'Sarah Doe'
);
重点是
不起作用,因为我只是花了几分钟的时间。但是,我想知道是否有任何类似的功能或例程与我刚才提到的相同。
希望我明白我想要的东西。
$sth = $pdo_connection->prepare("INSERT INTO `pdo_test` SET
`pdo_name` = 'John Doe',
`pdo_description` = 'John Doe who served in Vietnam and every other war game as a default name',
`pdo_text` = 'Some text BLABLA'
");
$sth ->execute();
$stmt = $pdo_connection->query("SELECT LAST_INSERT_ID()");
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$lastID = $result['LAST_INSERT_ID()'];
$stmt = $pdo_connection->prepare("SHOW COLUMNS FROM `pdo_test` WHERE EXTRA LIKE '%AUTO_INCREMENT%'");
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$AutoIncrementField = $row['Field'];
$stmt = $pdo_connection->prepare('SELECT * FROM `pdo_test` WHERE `'.$AutoIncrementField.'` = ?');
$stmt->execute(array($lastID));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
echo print_r($result);
结果:
Array
(
[pdo_id] => 64
[pdo_name] => John Doe
[pdo_counter] => 0
[pdo_description] => John Doe who served in Vietnam and every other war game as a default name
[pdo_text] => Some text BLABLA
)
但AutoIncrement字段似乎是必不可少的。
(由Edwin Lambregts提议)
请注意,此解决方案不是故障安全!因为查询选择最后插入的行...但是所有实例!因此,如果另一个用户刚刚插入了一个新行...您将看到他的输入而不是您的输入。如果更新发生在两者之间,则会发生这种情况。
$sth = $pdo_connection->prepare("INSERT INTO `pdo_test` SET
`pdo_name` = 'John Doe',
`pdo_description` = 'John Doe who served in Vietnam and every other war game as a default name',
`pdo_text` = 'Some text BLABLA'
");
$sth ->execute();
$stmt = $pdo_connection->prepare("SHOW COLUMNS FROM `pdo_test` WHERE EXTRA LIKE '%AUTO_INCREMENT%'");
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$AutoIncrementField = $row['Field'];
$stmt = $pdo_connection->prepare('SELECT * FROM `pdo_test` ORDER BY `'.$AutoIncrementField.'` DESC LIMIT 0,1');
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
结果是:
Array
(
[pdo_id] => 67
[pdo_name] => John Doe
[pdo_counter] => 0
[pdo_description] => John Doe who served in Vietnam and every other war game as a default name
[pdo_text] => Some text BLABLA
)
答案 0 :(得分:1)
我不确定你的问题是什么,但为了不弄乱你桌子里的东西,你必须实现这些:
桌面上有PK
(主键)。它为您提供了唯一标识每一行的方法。它应该是唯一标识每一行的字段或字段组合。理论上,他PK
的最佳候选者是存储在表中的实体的内在属性,用于标识实体。例如,对于Country
表,PK
的合适候选者是完整的国家/地区名称。在现实世界中,AUTO_INCREMENT
字段的发明是因为:
PK
的列或一组列;例如,用于存储程序生成的日志条目的表 - 即使其中一些条目相同,也必须存储所有条目;使用PK
字段为他们创建了一个人工AUTO_INCREMENT
; PK
的最佳候选列类型为string
时(上例中的国家/地区名称)或PK
的候选列是两列或更多列的集合时,将其用作PK
会对表格产生负面影响;人工PK
(创建为AUTO_INCREMENT
整数字段)会生成较小的索引,从而提高使用它的查询的速度。在INSERT
上,您可以为PK
生成一个值并将其放入查询中,或者依赖数据库为您生成一个值(如果PK
是AUTO_INCREMENT
字段。
PK
生成值,则需要确保表中尚不存在该值。您可以在INSERT
之前检查它是否不存在,或者您可以尝试INSERT
并检查它是否成功。即使您之前检查过,INSERT
仍然可能会失败,因为该脚本的另一个实例可以同时运行,并为INSERT
生成PK
相同的值。在这种情况下,您需要生成另一个值并再次尝试INSERT
,此工作流程将重复,直到成功为止。对我来说,这看起来不是一个好策略。您可以让数据库为PK
生成一个唯一值(为NULL
查询中PK
提供INSERT
或不提供MySQL
所有)然后询问它产生的价值。 AUTO_INCREMENT
为此目的提供LAST_INSERT_ID()
功能。摘自文档:
生成的ID在每个连接的服务器中维护。这意味着函数返回给定客户端的值是为该客户端影响
AUTO_INCREMENT
列的最新语句生成的第一个AUTO_INCREMENT
值。此值不受其他客户端的影响,即使它们生成自己的INSERT
值。此行为可确保每个客户端都可以检索自己的ID,而无需关心其他客户端的活动,也无需锁定或事务。
数据库处理所有事情:值是唯一的,它不会干扰尝试同时插入同一个表的脚本的其他实例(甚至其他代码); PK
成功,AUTO_INCREMENT
是唯一的,我会找回标识行的值,而不是别人的行。
有一个额外的列不是表中存储的实体的固有属性,这是为它产生的好处付出的小代价。
这只是一个指南,只有在帮助时才应添加人工AUTO_INCREMENTED
列。在上面带有国家/地区表的示例中,不需要PK
Country
列:
PK
表之前,您的应用程序可能会退役); CHAR[2]
有一个很好的候选人:是ISO-3166
国家/地区代码;甚至有两种口味:2个字母和3个字母 - 选择你最喜欢的;它是CHAR[3]
(或PK
),因为表格很小,因为{{1}}不会影响性能。答案 1 :(得分:0)
无需使用id即可获得最后插入的记录/行。
MySQL语法:
SELECT column_name FROM table_name
ORDER BY column_name DESC
LIMIT 1
它只会显示最后插入的记录。
答案 2 :(得分:-1)
$stmt = $db->prepare("...");
$stmt->execute();
$id = $db->lastInsertId();