correct syntax required with 'ON DUPLICATE KEY UPDATE


correct syntax required with 'ON DUPLICATE KEY UPDATE', SET option

我有form.php在其中创建或编辑记录。这个页面被一个'New Record'链接调用,在这种情况下,没有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
?>

刷新process.php,无论是否存在ID,都会插入副本。顺便说一下,我的ID列是主键,唯一索引,自动递增。那么,$query如何在插入或更新之前检查ID呢?[在日复一日的研究和实验之后,进入令人毛骨悚然的陈词滥调]

Thanks in advance, s

注。再保险:注:

我已经在我的脑海中包含了这一大块。php -请告诉我这是否包括注入:

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

修复sql注入漏洞
不能直接在查询中插入$_POST变量(或任何超全局$_*)
这是sql注入漏洞。

这样做:

$id = mysql_real_escape_string($_POST['ID']);
$invnumber = mysql_real_escape_string($_POST['invoice_number']);
....
etc 

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', .....

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

ON DUPLICATE KEY UPDATE invNumber = VALUES(invNumber)
                      , invDate = VALUES(invDate)
                      , .....
                      , comments = VALUES(comments)

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

首先,我必须说ON DUPLICATE KEY UPDATE不是用来替换UPDATE的,在这种情况下,我将对新数据使用INSERT,当现有数据被修改时使用UPDATE。

要在脚本中创建ON DUPLICATE KEY UPDATE触发器,还必须向INSERT添加ID,因为这是您引用的唯一列。

如果它找到了ID,它将触发查询的ON DUPLICATE部分。