while循环中的PHP mysqli_multi_query事务

时间:2017-01-03 15:39:32

标签: php mysql

PHP版本5.3.3,mysql 5.0.95

需要将数据从现有表迁移到两个相同的表。原始数据需要在插入两个新表之前进行解析。 (该代码未显示,因为我希望能够隔离此问题。) 希望使用交易来确保新表格相同。

task_id字段是test_timecard中的自动增量,并且是test_timecar_2中的unsigned mediumint。

引擎是两个表的InnoDB。

单独的查询有效:

$timecard_data_results = array();
$fill_old_data_array_def = " SELECT task_id, company_id, employee_id, location, task_name, task_start_time, task_end_time, tccomment FROM timecard WHERE company_id = '" . $company_request . "' AND employee_id = '" . $employee_request . "' AND DATE(task_start_time) < '" . $new_text_format_date . "' AND (DATE(task_end_time) > '2014-12-31' OR DATE(task_end_time) = '2000-01-01') ORDER BY task_start_time";
$timecard_data_results = mysqli_query($conn, $fill_old_data_array_def);

while($timecard_record = mysqli_fetch_assoc($timecard_data_results)) {

    $company_id = $timecard_record['company_id'];
    $employee_id = $timecard_record['employee_id'];
    $location = $timecard_record['location'];
    $task_name = $timecard_record['task_name'];
    $task_start_time = $timecard_record['task_start_time'];
    $task_end_time = $timecard_record['task_end_time'];
    $tccomment = $timecard_record['tccomment'];

    $troubleshoot_def = "INSERT INTO test_timecard (company_id, employee_id, location, task_name, task_start_time, task_end_time, tccomment) VALUES ('" . $company_id . "', '" . $employee_id . "', '" . $location . "', '" . $task_name . "', '" . $task_start_time . "', '" . $task_end_time . "', '" . $tccomment . "')"; 
    $troubleshoot_2_def = "INSERT INTO test_timecard_2 (task_id, company_id, employee_id, location, task_name, task_start_time, task_end_time, tccomment) VALUES (LAST_INSERT_ID(), '" . $company_id . "', '" . $employee_id . "', '" . $location . "', '" . $task_name . "', '" . $task_start_time . "', '" . $task_end_time . "', '" . $tccomment . "')";     
    $troubleshoot = mysqli_query ($conn, $troubleshoot_def);
    $troubleshoot_2 = mysqli_query ($conn, $troubleshoot_2_def);
}

与mysqli_multi_query的事务只向两个表插入一行。没有报告错误。

$timecard_data_results = array();
$fill_old_data_array_def = " SELECT task_id, company_id, employee_id, location, task_name, task_start_time, task_end_time, tccomment FROM timecard WHERE company_id = '" . $company_request . "' AND employee_id = '" . $employee_request . "' AND DATE(task_start_time) < '" . $new_text_format_date . "' AND (DATE(task_end_time) > '2014-12-31' OR DATE(task_end_time) = '2000-01-01') ORDER BY task_start_time";
$timecard_data_results = mysqli_query($conn, $fill_old_data_array_def);

while($timecard_record = mysqli_fetch_assoc($timecard_data_results)) {

    $company_id = $timecard_record['company_id'];
    $employee_id = $timecard_record['employee_id'];
    $location = $timecard_record['location'];
    $task_name = $timecard_record['task_name'];
    $task_start_time = $timecard_record['task_start_time'];
    $task_end_time = $timecard_record['task_end_time'];
    $tccomment = $timecard_record['tccomment'];

    $troubleshoot_def = "START TRANSACTION; INSERT INTO test_timecard (company_id, employee_id, location, task_name, task_start_time, task_end_time, tccomment) VALUES ('" . $company_id . "', '" . $employee_id . "', '" . $location . "', '" . $task_name . "', '" . $task_start_time . "', '" . $task_end_time . "', '" . $tccomment . "'); INSERT INTO test_timecard_2 (task_id, company_id, employee_id, location, task_name, task_start_time, task_end_time, tccomment) VALUES (LAST_INSERT_ID(), '" . $company_id . "', '" . $employee_id . "', '" . $location . "', '" . $task_name . "', '" . $task_start_time . "', '" . $task_end_time . "', '" . $tccomment . "'); COMMIT;"; 
    $troubleshoot = mysqli_multi_query ($conn, $troubleshoot_def);
}    

难住了。

1 个答案:

答案 0 :(得分:0)

$troubleshoot_def = "INSERT INTO test_timecard (company_id, employee_id, location, task_name, task_start_time, task_end_time, tccomment) VALUES ('" . $company_id . "', '" . $employee_id . "', '" . $location . "', '" . $task_name . "', '" . $task_start_time . "', '" . $task_end_time . "', '" . $tccomment . "')"; 
    $troubleshoot_2_def = "INSERT INTO test_timecard_2 (task_id, company_id, employee_id, location, task_name, task_start_time, task_end_time, tccomment) VALUES (LAST_INSERT_ID(), '" . $company_id . "', '" . $employee_id . "', '" . $location . "', '" . $task_name . "', '" . $task_start_time . "', '" . $task_end_time . "', '" . $tccomment . "')";     

这里有很多问题。首先,将几乎相同的数据插入两个不同的表中根本没有任何意义。实际上,当操作完成时,您有三个表具有几乎相同的数据,即test_timecard_2test_timecardtimecard

其次,您要插入未转义的数据。由于数据来自您的另一个表,因此SQL注入的可能性不大,但查询仍有可能失败。具体来说,我在谈论这样的代码:

VALUES ('" . $company_id . "', '" . $employee_id . "', '" . $location . "', '" . $task_name . "', '" . $task_start_time . "', '" . $task_end_time . "', '" . $tccomment . "')"; 

第三,你几乎不需要做SELECT - LOOP - INSERT,因为mysql有一个内置的INSERT SELECT命令。

INSERT INTO test_timecard (company_id, employee_id, location, task_name, task_start_time, task_end_time, tccomment) 
SELECT * FROM time_card

注意使列正确(上面只是代码的两个部分的复制粘贴)