2011-10-05 69 views
1

我有form.php在其中創建或編輯記錄。這個頁面被一個'New Record'鏈接調用,在這種情況下沒有ID集合,或者通過'EDIT'鏈接調用$ _GET ['ID']來設置(並用於檢索記錄)。'ON DUPLICATE KEY UPDATE',SET選項需要正確的語法

計劃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的INSERT愚弄是否有一個ID或沒有。我的'ID'列,btw,是主鍵,唯一索引,自動遞增。那麼,如何在$查詢或者插入或UPDATEing之前檢查的ID?[進入拉頭髮出的陳詞濫調隨後幾天的研究和實驗夜]

在此先感謝,S

附:回覆:注:

我已經包括此塊在我head.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); 
    } 
?> 
+0

您可以通過引用'VALUES'來簡化您的'ON DUPLICATE KEY UPDATE'子句。請參閱http://stackoverflow.com/questions/302544/is-there-a-way-to-do-an-insert-on-duplicate-key-udpate-in-zend-framework/1207076#1207076 – 2011-10-05 23:58:29

+0

感謝鳳凰城。我一直堅持SET選項,因爲我發現它更易於閱讀。根據我迄今爲止閱讀的內容,我不瞭解使用VALUES的其他優點,除非它是解決我目前問題的唯一方案。乾杯! – shecky

回答

6

修復了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) 

請勿在更新部分使用主鍵和唯一鍵
請注意,insert部分中的字段與您的update部分中的字段完全相同是沒有意義的。
如果您使用此語句,則更新部分必須排除SET子句中的所有主鍵和唯一鍵!

+1

正確的語法也可以是:'ON DUPLICATE KEY UPDATE invNumber = VALUES(invNumber),invDate = VALUES(invDate),..... ' –

+0

而且我認爲這是'重複密鑰更新'。 'ON DUPLICATE KEY ** SET **'有效的語法? –

+0

謝謝Johan&ypercube。請注意我編輯的問題;我非常感謝確認我包含在head.php中的代碼足以防止注入。 – shecky

1

首先我必須說,對重複密鑰更新不彪替換UPDATE,在這種情況下,我將使用INSERT作爲新數據,並在現有數據被修改時更新UPDATE。

要在您的腳本中創建ON D​​UPLICATE KEY UPDATE觸發器,您還必須將該ID添加到INSERT中,因爲這是您正在使用的唯一列。

如果它找到該ID,它將觸發查詢的ON DUPLICATE部分。

+0

我喜歡你,但你忘記了SQL注入,所以我不能:-( – Johan

+2

呵呵,我仍然在學習如何「教」,這可能是我沒有提到注入問題的原因:)從每個帖子我都會學習新的東西,就像現在一樣解決您發現的所有問題,即使它們不是原始問題的一部分:P – Ole

+0

Thx Helbom。正如我注意到的,我的原始設置是按照您的描述:插入新數據,更新編輯過的數據......但後來我必須解決模糊問題,並且無法在插入查詢中使用ON DUPLICATE KEY UPDATE,所以我試圖簡化爲帶有ON DUPLICATE KEY UPDATE的插入查詢,但我也遇到了問題 – shecky

相關問題