简体   繁体   English

while循环中的PHP mysqli_multi_query事务

[英]PHP mysqli_multi_query transaction in while loop

PHP version 5.3.3, mysql 5.0.95 PHP版本5.3.3,mysql 5.0.95

Need to migrate data from an existing table to two identical tables. 需要将数据从现有表迁移到两个相同的表。 Data from original needs parsing before insert into the two new tables. 原始数据需要在插入两个新表之前进行解析。 (That code not shown as I'm hoping to isolate this problem.) Wanted to use transaction to insure new tables are identical. (该代码未显示,因为我希望能够隔离这个问题。)想要使用事务来确保新表是相同的。

task_id field is autoincrement in test_timecard and is unsigned mediumint in test_timecar_2. task_id字段是test_timecard中的自动增量,是test_timecar_2中的unsigned mediumint。

Engine is InnoDB for both tables. 引擎是两个表的InnoDB。

Separate queries works: 单独的查询有效:

$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);
}

transaction with mysqli_multi_query inserts one row only to both tables. 使用mysqli_multi_query的事务只向两个表插入一行。 No errors reported. 没有错误报告。

$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);
}    

Stumped. 难住了。

$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 . "')";     

There are lot's of problems here. 这里有很多问题。 First is that it does not make any sense at all to insert nearly identical data into two different tables. 首先,将几乎相同的数据插入两个不同的表中根本没有任何意义。 In fact when the operation completes you have three tables with nearly identical data namely test_timecard_2 , test_timecard and timecard 事实上在操作完成时,你有几乎相同的数据,即三个表test_timecard_2test_timecardtimecard

Secondly you are inserting unescaped data. 其次,您正在插入未转义的数据。 Since data comes from another of your tables there isn't much chance of an sql injection but there is still a likelyhood that the queries will fail. 由于数据来自您的另一个表,因此SQL注入的可能性不大,但查询仍有可能失败。 Specifically I am talking about code like this: 具体来说,我在谈论这样的代码:

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

Thirdly, you almost never need to do SELECT - LOOP - INSERT because mysql has a built in INSERT SELECT command. 第三,你几乎不需要做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

take care to get the columns right (the above is just a copy paste from two sections of your code) 注意使列正确(上面只是代码的两个部分的复制粘贴)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM