我目前有一个脚本,可以在使用表单添加新元素时自动插入新数据。
我使用
public string PDO::lastInsertId ([ string $name = NULL ] )
当然是逻辑。现在我只想知道如果表没有 ID 字段和没有自动增量字段,这是否会导致任何问题。
撇开事实不谈,如果这意味着使用了错误的数据库结构。我想确保这个例程在任何情况下都有效。好的数据库或坏的数据库结构。这应该没关系。
我的意思是我想返回包含数据的行,以便我可以搜索它。
例如
1
将新数据插入数据库
$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'
);
3
然后使用与刚刚插入的完全相同的数据更新最后插入的行
$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'
);
关键是
步骤 2
不起作用,因为我只是一次编了几分钟。但是,我想知道是否有任何类似的函数或例程与我刚才提到的功能相同。
希望清楚我想要什么。
我的解决方案最终是:
$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
)
但是自动增量字段似乎是必不可少的。
第二种解决方案,但仍带有自动增量字段。
(提议者:埃德温·兰布雷茨)
请注意,此解决方案不是故障安全的!!因为查询会选择最后插入的行...但在所有情况下!因此,如果另一个用户刚刚插入了新行...你将看到他的输入,而不是你的。如果更新发生在两者之间,则可能会发生这种情况。
$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
)
我不确定你的问题是什么,但是,为了不弄乱表中的东西,你必须实现这些东西:
-
表上有
PK
(主键)。它为您提供了一种唯一标识每一行的方法。它应该是一个字段或唯一标识每一行的字段组合。从理论上讲,PK
的最佳候选者是存储在标识实体的表中的实体的固有属性。例如,对于Country
表,PK
的良好候选项是完整的国家/地区名称。在现实世界中,发明AUTO_INCREMENT
场是因为:- 有些表只是没有可以用作
PK
的列或一组列; 例如,用于存储程序生成的日志条目的表 - 即使其中一些条目相同,也必须存储所有条目; 使用AUTO_INCREMENT
字段为它们创建人工PK
; - 当
PK
的最佳候选列的类型为string
(上例中的国家/地区名称)或PK
候选项是一组两列或更多列时,将其用作PK
将对表的性能产生负面影响;人工PK
(创建为AUTO_INCREMENT
整数字段)生成较小的索引,从而提高使用它的查询的速度。
- 有些表只是没有可以用作
-
在
INSERT
上,您可以为PK
生成一个值并将其放入查询中,也可以依靠数据库为您生成一个值(如果PK
是AUTO_INCREMENT
字段)。- 如果为
PK
生成值,则需要确保表中尚不存在该值。您可以在INSERT
之前检查它是否存在,也可以尝试INSERT
并检查它是否成功。即使您之前检查过,INSERT
仍然可能失败,因为脚本的另一个实例可以同时运行,为PK
生成和INSERT
相同的值。在这种情况下,您需要生成另一个值并尝试再次INSERT
,此工作流将重复,直到成功。这对我来说似乎不是一个好的策略。 -
您可以让数据库为您的
PK
生成唯一值(通过在INSERT
查询中为PK
提供NULL
或根本不提供它),然后询问它生成的值。MySQL
为此提供了LAST_INSERT_ID()
功能。文档摘录:生成的 ID 基于每个连接在服务器中维护。这意味着函数返回给给定客户端的值是为该客户端影响
AUTO_INCREMENT
列的最新语句生成的第一个AUTO_INCREMENT
值。此值不受其他客户端的影响,即使它们生成自己的AUTO_INCREMENT
值也是如此。此行为可确保每个客户端都可以检索自己的 ID,而无需担心其他客户端的活动,也不需要锁或事务。数据库负责所有事情:值是唯一的,它不会干扰尝试同时插入同一表中的脚本(甚至其他代码)的其他实例;
INSERT
成功,PK
是唯一的,我得到标识我的行的值,而不是其他人的行。
- 如果为
如果附加列不是存储在表中的实体的固有属性,那么对于它产生的好处来说,这是一个很小的代价。
这只是一个指南,只有在有帮助时才应添加人工AUTO_INCREMENT
列。在上面的国家/地区表中,不需要PK
的AUTO_INCREMENTED
列:
- 该表仅包含几百行;其中没有插入或删除(事实上有,但只是偶尔一次;您的应用程序可能在需要更改
Country
表之前就已停用); PK
有一个很好的候选者:是ISO-3166
国家代码;它甚至有两种风格:2个字母和3个字母 - 选择你最喜欢的;它是一个CHAR[2]
(或CHAR[3]
),因为桌子太小了,因为它PK
不会以任何方式影响性能。
当然可以在不使用id的情况下获取最后插入的记录/行。
MySQL 语法:
SELECT column_name FROM table_name
ORDER BY column_name DESC
LIMIT 1
它将仅显示上次插入的记录。
来源: http://www.w3schools.com/sql/sql_func_last.asp