我有一个场景,如果我的所有插入查询都能正常工作,我将如何确保。我正在使用PHP作为后端编码和mysql用于我的数据库。下面我简要描述一下我的问题。
我有两张桌子。一个表用于login_details,另一个表用于personal_details。我的表结构在这里。
表login_details这里user_id是唯一的主键,sl_num是自动增量:
th{
padding: 3px;
border: 1px solid black;
}
td{
padding: 3px;
border: 1px solid black;
}
<table>
<thead>
<th>sl_num</th>
<th>user_id</th>
<th>email</th>
<th>password</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>123</td>
<td>daniel@gmail.com</td>
<td>5567</td>
</tr>
<tr>
<td>2</td>
<td>246</td>
<td>lucy@yahoo.com</td>
<td>9908</td>
</tr>
</tbody>
</table>
我的第二张表是personal_details。这里user_id也是主键,这个键也保持两个表之间的关系,sl_num是自动增量的:
th{
padding: 3px;
border: 1px solid black;
}
td{
padding: 3px;
border: 1px solid black;
}
<table>
<thead>
<th>sl_num</th>
<th>user_id</th>
<th>name</th>
<th>address</th>
<th>age</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>123</td>
<td>Daniel</td>
<td>San Francisco</td>
<td>23</td>
</tr>
<tr>
<td>2</td>
<td>246</td>
<td>Lucy</td>
<td>London</td>
<td>27</td>
</tr>
</tbody>
</table>
并且,我使用此代码在这些表中插入值。
<?php
$user_id = uniqid();
$email = $_POST['email'];
$password = $_POST['password'];
$name = $_POST['name'];
$address = $_POST['address'];
$age = $_POST['age'];
$con = mysqli_connect('localhost', 'username', 'password',
'user_db');
$query = "INSERT INTO `login_details` (`user_id`, `email`,
`password`) VALUES ('$user_id', '$email', '$password')";
mysqli_query($con,$query);
$query2 = "INSERT INTO `personal_details` (`user_id`, `name`,
`address`, `age`) VALUES ('$user_id', '$name', '$address',
'$age')";
mysqli_query($con,$query);
echo 'User created successfully';?>
但有线问题曾经发生过一次。第三个用户名'John Doe'试图创建他的帐户。 personal_details表的详细信息已成功插入,但由于某些原因未插入login_details的详细信息。因此,用户'John Doe'在桌面上有个人信息,但因为他没有任何登录信息,所以他无法登录。
那么,这种多插入情况的最佳解决方案是什么。我该如何防止这种情况发生。这意味着,如果将一行插入login_details,则系统必须确保相关行也插入到personal_details表中。如果成功插入了两个,那么事务就会发生,或者如果插入一行而其他行没有插入,那么系统将自动丢弃插入的行并显示失败消息。
答案 0 :(得分:0)
查询失败的原因可能是因为您没有转义SQL上下文中的任何变量。这意味着如果其中一个字符串中存在'
,则SQL语句将变为无效。这是known as an SQL injection attack,很快就会使您的应用程序容易受到攻击。
减轻这些攻击的常用方法是use a prepared statement instead。
如果第一个查询失败,那至少可以让你取消第二个查询。但是,如果第二个失败了(由于某些原因,当你使用了正确的......如果你已经正确地逃脱了你的变量,那就不会发生 )可以运行等等。)。
您可以将两个语句都包装在SQL事务中,然后在任何查询失败时提交或回滚事务。这假设MySQL中的表/数据库类型支持事务,并且禁用自动提交。
您可以通过调用mysqli_begin_transaction($con)
来启动与mysqli的交易。
然后,您可以通过调用mysqli_commit
或mysqli_rollback
来提交或回滚交易。
要检测前一个语句是否失败,您可以拨打mysqli_error
。