mysql INSERT背靠背随机失败


mysql INSERTs back to back are failing randomly

我几乎已经尝试了我所知道的一切,但未能修复这组相当奇怪的错误。

我正在尝试在一个消息que表中制作4个INSERT。

$email_start_message、$sms_start_mmessage、$email_end_message和$sms_end_message是存储为Blob的字符串,因为将来它们将具有HTML和图像。

代码如下:

$response = array();
$send_status = 0;
$seller_id = 1275;
$re1 = mysql_query("INSERT INTO pos_msg_que(send_status, sid, uid, alert_type, alert_data, send_time) VALUES ('$send_status','$seller_id','$uid','1','mysql_real_escape_string($email_start_message)','$start_time');");
if (!$re1 == 'false') {
  $response['start_email_alert'] =  '1';
} else {
  $response['start_email_alert'] =  '0';
}
$re2 = mysql_query("INSERT INTO pos_msg_que(send_status, sid, uid, alert_type, alert_data, send_time) VALUES ('$send_status','$seller_id','$uid','2','mysql_real_escape_string($sms_start_message)','$start_time');");
if (!$re2 == 'false') {
  $response['start_sms_alert'] =  '1';
} else {
  $response['start_sms_alert'] =  '0';
}
$re3 = mysql_query("INSERT INTO pos_msg_que(send_status, sid, uid, alert_type, alert_data, send_time) VALUES ('$send_status','$seller_id','$uid','3','mysql_real_escape_string($email_end_message)','$end_time');");
if (!$re3 == 'false') {
  $response['end_email_alert'] =  '1';
} else {
  $response['end_email_alert'] =  '0';
}
$re4 = mysql_query("INSERT INTO pos_msg_que(send_status, sid, uid, alert_type, alert_data, send_time) VALUES ('$send_status','$seller_id',  '$uid','4','mysql_real_escape_string($sms_end_message)','$end_time');");
if (!$re4 == 'false') {
  $response['end_sms_alert'] =  '1';
} else {
  $response['end_sms_alert'] =  '0';
}
echo json_encode($response);

}

表格结构为:

+-----------------+------------+------+-----+-------------------+-----------------------------+
| Field           | Type       | Null | Key | Default           | Extra                       |
+-----------------+------------+------+-----+-------------------+-----------------------------+
| id              | int(8)     | NO   | PRI | NULL              | auto_increment              |
| send_status     | int(11)    | NO   |     | NULL              |                             |
| sid             | int(8)     | NO   |     | NULL              |                             |
| uid             | int(8)     | NO   |     | NULL              |                             |
| alert_type      | tinyint(2) | NO   |     | NULL              |                             |
| alert_data      | blob       | NO   |     | NULL              |                             |
| send_time       | datetime   | NO   |     | NULL              |                             |
| advance_time    | int(3)     | NO   |     | NULL              |                             |
| last_attempt_at | timestamp  | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-----------------+------------+------+-----+-------------------+-----------------------------+

现在,当我运行此代码时,JSON响应是:

{"start_email_alert":"1 0","start_sms_alert":"012","end_email_alert":"1 12","end_sms_alert":"1 12"}

问题是:

  1. 第一个插入总是获得插入ID 0
  2. 第二次插入总是失败,但ID会自动递增
  3. 第三次和第四次插入正在进行,但使用的ID是步骤2的ID,因此它们会有效地覆盖
  4. 由于我无法理解的原因,alert_type在DB中总是显示1。尽管我插入的是2,3

有人能帮我弄清楚吗?

在两次被否决和一次被支持后,我对代码到底出了什么问题感到困惑。多亏了@AirThomas和@Jasper,我格式化了代码并采用了一些最佳实践,这帮助我解决了这个问题。

问题出在字符串上。它们只有一个引号,不知何故没有被转义(主要是因为一些奇怪的字符编码问题。我没有详细说明)。相反,我使用了(phpfreks)中的一个简单函数来确保,在逃离时,我不会想尽一切办法。功能是:

function cleanStr($str){
  $str = trim($str);
  if($str == "") return;
  $str = stripslashes($str);//STRIP ' slashes
  if (function_exists(mysqli_real_escape_string)){
    $str = mysqli_real_escape_string($str);
  }else{
    $str = mysql_real_escape_string($str);
  }
  //CONVERT TO HTML
  $str = htmlspecialchars($str);
  //LAST CLEAN UP
  $str = preg_replace("#''#","",$str);
  return $str;
}

在转义字符串并参数化代码(编辑问题以显示最新的代码)后,插入就像一个符咒。

我今天学到的东西:

  • 正确转义字符串,而不仅仅是mysql_real_eescape_string
  • 像这样使用mysql_error()来捕获mysql错误

echo-mysql_errno()。":"。mysql_error()。"''n";

  • 设置查询格式并尽可能多地对其进行参数化
  • 在SO上发帖之前正确格式化代码,否则你甚至都不会
  • 使用PDO或mysqli

我刚刚开始编码(4周前),所以很抱歉出现明显的错误。

感谢大家