当语句在MySQL中工作正常时,如何解决PHP中的语法错误?

时间:2019-02-08 22:11:55

标签: php mysql

我正在使用PHP / MySQL存储从网页收集的数据。我正在

  

您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在'INSERT INTO narrative_photos VALUES(`filename`,`narrative_id`)VALUES('ash_02

当我将PHP生成的语句粘贴到MySQL控制台中时,该语句可以正常工作。

这是PHP代码:

foreach ($files['pictures']['final_name'] as $key => $final_name) {
    $sql .= "INSERT INTO narrative_photos ";
    $sql .= "(`filename`, `narrative_id`) ";
    $sql .= "VALUES (";
    $sql .= "'" . db_escape($db, $final_name) . "', ";
    $sql .= "'LAST_INSERT_ID()'); ";
}

它产生的外观如下:

INSERT INTO narrative_photos VALUES (`filename`, `narrative_id`) VALUES ('ash_020819-140257.png', 3);

如果我将其粘贴到MySQL中,它将起作用。但是,如果我注释掉PHP代码并替换为:

 $sql .= "INSERT INTO narrative_photos VALUES (`filename`, `narrative_id`) VALUES ('ash_020819-140257.png', 3);";

它继续引发MySQL错误。

我已经玩了两个小时了,但我不知道我的错误在哪里。我将再欣赏另一组眼睛。谢谢!

编辑:这是上下文的整个功能。

function insert_narrative($narrative, $files) {
    global $db;

    $sql = "INSERT INTO narratives ";
    $sql .= "(date, positive_thing, what_you_did, goals, plan, entered_by, library_id) ";
    $sql .= "VALUES (";
    $sql .= "'" . db_escape($db, $narrative['sqldate']) . "', ";
    $sql .= "'" . db_escape($db, $narrative['positive_thing']) . "', ";
    $sql .= "'" . db_escape($db, $narrative['what_you_did']) . "', ";
    $sql .= "'" . db_escape($db, $narrative['goals']) . "', ";
    $sql .= "'" . db_escape($db, $narrative['plan']) . "', ";
    $sql .= "'" . db_escape($db, $narrative['entered_by']) . "', ";
    $sql .= "'" . db_escape($db, $_SESSION['library_id']) . "'";
    $sql .= "); ";

    if (!empty($files['pictures']['final_name'])) {
        foreach ($files['pictures']['final_name'] as $key => $final_name) {
            $sql .= "INSERT INTO narrative_photos ";
            $sql .= "(`filename`, `narrative_id`) ";
            $sql .= "VALUES (";
            $sql .= "'" . db_escape($db, $final_name) . "', ";
            $sql .= "LAST_INSERT_ID()); ";

        }
    }
    $result = mysqli_query($db, $sql);
    if ($result) {
        return true;
    } else {
        echo mysqli_error($db);
        db_disconnect($db);
        exit;
    }
}

编辑#2: 我只是意识到,独立于语法错误,我的方法将行不通,因为LAST_INSERT_ID可能将为每个插入选择ID,而不是仅使用主表中的ID。我已经修改了该函数,但是在SET @narrative_id上​​仍然出现语法错误。这是代码。

$sql = "INSERT INTO narratives ";
$sql .= "(date, positive_thing, what_you_did, goals, plan, entered_by, library_id) ";
$sql .= "VALUES (";
$sql .= "'" . db_escape($db, $narrative['sqldate']) . "', ";
$sql .= "'" . db_escape($db, $narrative['positive_thing']) . "', ";
$sql .= "'" . db_escape($db, $narrative['what_you_did']) . "', ";
$sql .= "'" . db_escape($db, $narrative['goals']) . "', ";
$sql .= "'" . db_escape($db, $narrative['plan']) . "', ";
$sql .= "'" . db_escape($db, $narrative['entered_by']) . "', ";
$sql .= "'" . db_escape($db, $_SESSION['library_id']) . "'";
$sql .= "); ";
$sql .= "SET @narrative_id = LAST_INSERT_ID()";

if (!empty($files['pictures']['final_name'])) {
    foreach ($files['pictures']['final_name'] as $key => $final_name) {
        $sql .= "INSERT INTO narrative_photos ";
        $sql .= "(`filename`, `narrative_id`) ";
        $sql .= "VALUES (";
        $sql .= "'" . db_escape($db, $final_name) . "', ";
        $sql .= "@narrative_id); ";

    }
}

2 个答案:

答案 0 :(得分:2)

如果您要进行一个查询以插入所有值,则不必每次都包含查询的INSERT部分,而只需添加一组新值即可。您可以使用类似这样的东西。请注意,LAST_INSERT_ID()不应用引号引起来,因为这会插入文字字符串"LAST_INSERT_ID()"而不是值。

$sql  = "INSERT INTO narrative_photos (`filename`, `narrative_id`) VALUES ";
$values = array();
foreach ($files['pictures']['final_name'] as $final_name) {
    $values[] = "('" . db_escape($db, $final_name) . "', LAST_INSERT_ID())";
}
$sql .= implode(', ', $values);

注释

我假设您实际上希望所有这些文件名在narrative_id中都具有相同的值,这将链接回另一个表。

尽管从外观上看,这些值已经过过滤(我想它们是实际的系统文件名),但是代码仍然很容易受到SQL注入的攻击。 This questionthis question为如何使用带参数数组的预备语句提供了一些很好的建议。

答案 1 :(得分:0)

我不明白为什么您将每一行连接到一个变量而不是仅仅执行整个语句。另外,在您的示例中,您两次使用import * as myServices from '../feature1/services';是错误的。我不明白为什么要在循环内创建SQL语句,但是却从不执行它,而这是您所需要的。我不知道您使用的是什么API,但这是一个示例。

VALUES