我在数据库中有一个表包含_id
列,这是该表的主键,实际上这个列值是由自动增量方法设置的,有没有任何安全的方法来获取auto的值当我插入时给予行i的增量值???我看到一个解决方案说:“在插入查询后立即调用mysql_insert_id()
。”是否可以安全使用(即如果在不同的线程中相同的脚本,它会得到一个错误的值)???如果没有,有没有办法在PHP中制作同步块?
答案 0 :(得分:3)
据我所知,从mysql_insert_id返回的id是从当前连接(mysql_connect)的最后一次插入查询到sql数据库的自动增量id。在查询之后必须立即调用它的唯一原因是,如果你在彼此之后运行两个插入查询,mysql_insert_id只返回最后一个查询。从第一个查询中获取id是不可靠的。此外,它从最后一个查询中获取id,因此如果您执行了插入然后更新,则运行mysql_insert_id。它将返回0,因为最后一个查询(更新)不是插入。
另外,php只调用mysql函数mysql_insert_id。从mysql手册:
mysql_insert_id()的值仅受发出的语句的影响 在当前客户端连接中。它不受陈述的影响 由其他客户发布。
答案 1 :(得分:1)
是; $ id = mysql_insert_id();在您的查询后直接。
答案 2 :(得分:0)
如果你的不同线程都使用自己的连接到MySQL服务器,它应该没问题。如果没有,您可能必须使用互斥锁或信号量,这应该由您的线程库提供。
答案 3 :(得分:0)
这样做通常很安全,但可能存在同步问题。
我建议将您的sqls放入交易区:
mysql_query('BEGIN TRANSACTION');
mysql_query('INSERT...');
$x = mysql_insert_id();
mysql_querry('COMMIT');
编辑:你也可以在表上放一个写锁,直到你读到id然后释放锁。但是如果你有同步问题(同一个线程),你只需要这个
答案 4 :(得分:0)
在PDO中,正确的方法是使用PDO::lastInsertId()
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try{
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', 'john@example.com')";
// use exec() because no results are returned
$conn->exec($sql);
$last_id = $conn->lastInsertId();
echo "New record created successfully. Last inserted ID is: " . $last_id;
}catch(PDOException $e){
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
答案 5 :(得分:0)
同样,您可以使用一个查询来获取自动增量ID,例如:
INSERT INTO table_name(field_1,field_2) VALUES(:field_1,:field_2) RETURNING id;
或
INSERT INTO table_name (field_1) OUTPUT INSERTED.id VALUES (?);
两个都返回您的自动增量ID 关于: https://www.php.net/manual/en/pdo.lastinsertid.php