'ON DUPLICATE KEY UPDATE',SET选项需要正确的语法

she*_*cky 1 php mysql duplicates

我有form.php,其中创建或编辑记录.此页面由aa'新记录'链接调用,在这种情况下没有ID设置,或者通过'EDIT'链接调用,在这种情况下设置$ _GET ['ID'](并用于检索记录).

计划A是:将form.php提交到process.php; 在process.php中,如果有ID,则查询为UPDATE,否则为INSERT.有一次,这个if/else按预期工作但刷新了创建的欺骗,所以我开始玩'ON DUPLICATE KEY UPDATE',但是没有成功.计划B最终发生在我的小脑中:不应该是process.php只有一个INSERT查询,并且添加了ON DUPLICATE KEY UPDATE?还没有这个工作.

process.php:

    <?php
    // get $_POST from form.php *** note: no ID if it's a New Record ***
    $id     = $_POST['ID'];
    $invNumber  = $_POST['invoice-number'];
    $invDate    = $_POST['invoice-date'];
    $projNumber = $_POST['project-number'];
    $client = $_POST['client'];
    $issueDate  = $_POST['issue-date'];
    $task       = $_POST['task'];
    $subTotal   = $_POST['sub-total'];
    $tax        = $_POST['tax'];
    $invTotal   = $_POST['invoice-total'];
    $datePaid1  = $_POST['payment-date-1'];
    $datePaid2  = $_POST['payment-date-2'];
    $comments   = $_POST['comments'];

    if (isset($_POST['submit'])) {
        $query = "INSERT INTO $table SET
            invNumber   = '$invNumber',
            invDate     = '$invDate',
            projNumber  = '$projNumber',
            client      = '$client',
            task            = '$task',
            issueDate   = '$issueDate',
            subTotal        = '$subTotal',
            tax         = '$tax',
            invTotal        = '$invTotal',
            datePaid1   = '$datePaid1',
            datePaid2   = '$datePaid2',
            comments        = '$comments'

            ON DUPLICATE KEY UPDATE
            invNumber   = $invNumber,
            invDate     = $invDate,
            projNumber  = $projNumber,
            client      = $client,
            task            = $task,
            issueDate   = $issueDate,
            subTotal        = $subTotal,
            tax         = $tax,
            invTotal        = $invTotal,
            datePaid1   = $datePaid1,
            datePaid2   = $datePaid2
            ID              = LAST_INSERT_ID(ID)
        ";

        $lastID = mysql_insert_id();
        $result = mysql_query($query) or die(mysql_error());
        $affRows = mysql_affected_rows();
        if (($result) && ($affRows))    {
            echo "<p class=\"status\">
            <strong>RECORD #".$id." UPDATED.</strong><br />
            <strong>Records updated: " . $affRows . "</strong>
            </p>";
        } // END if ($result ...
    } // END CASE 1
?>
Run Code Online (Sandbox Code Playgroud)

刷新process.php INSERT会欺骗是否有ID.我的'ID'列,顺便说一句,是主键,唯一索引,自动增量.那么$ query在INSERTing或UPDATE之前如何检查ID?[在研究和实验的日夜之后进入拉扯陈词滥调]

提前谢谢,s

ps re:注射:

我一直把这个块包括在我的脑袋里.请告诉我这是否包括注射:

<?php
    // prevent SQL Injection in $_POST variables:
    foreach ($_POST as $key => $value)  {
        $_POST[$key] = mysql_real_escape_string($value);
    }

    // prevent SQL Injection in $_GET variables:
    foreach ($_GET as $key => $value)   {
        $_GET[$key] = mysql_real_escape_string($value);
    }
?>
Run Code Online (Sandbox Code Playgroud)

Joh*_*ica 6

修复SQL注入漏洞
您不能将$_POSTvars (或任何超级全局$_*)直接插入查询.
这是一个SQL注入漏洞.

改为:

$id = mysql_real_escape_string($_POST['ID']);
$invnumber = mysql_real_escape_string($_POST['invoice_number']);
....
etc 
Run Code Online (Sandbox Code Playgroud)

正确的语法INSERT .. ON DUPLICATE KEY UPDATE是:

INSERT INTO TABLE (ID,invNumber,invDate,projNumber,client,task,issueDate
                  ,subTotal,tax,invTotal,datePaid1,datePaid2,comments)
VALUES ('$id','$invNumber','$invDate','$projNumber','$client','$task'
       ,'$issueDate','$subTotal','$tax','$invTotal','$datePaid1','$datePaid2'
       ,'$comments')
ON DUPLICATE KEY UPDATE invNumber = '$invNumber', invDate = '$invDate', .....
Run Code Online (Sandbox Code Playgroud)

最后一行也可以更改为(因此,您的代码不会将参数数据传递两次):

ON DUPLICATE KEY UPDATE invNumber = VALUES(invNumber)
                      , invDate = VALUES(invDate)
                      , .....
                      , comments = VALUES(comments)
Run Code Online (Sandbox Code Playgroud)

不要在更新部件中使用主键和唯一键
请注意,在您的insert部件中具有与您的update部件中完全相同的字段是没有意义的.
如果使用此语句,则更新部分必须从该SET子句中排除所有主键和唯一键!