2014-09-02 100 views
0

爲什麼下面的代碼執行查詢排除(DELETE FROM ...),甚至在插入查詢時出錯?交易PHP和Oracle

錯誤消息:

陣列 ([0] => ORA-00001:restriçãoexclusiva(INTRANETDESENVOLVIMENTO.PK_TB100442_MAIL_BACKUP)violada Linha:260 )

我接着這個例子:http://php.net/manual/pt_BR/function.oci-rollback.php

我的功能:

public function minimizarSGMail() 
{ 
    $conn = oci_connect(IC::get('database.username'), IC::get('database.password'), IC::get('database.tns')); 
    $linhas = 5; 
    $dias = 90; 
    $erro = array(); 

    // Prepara o sql de insert 
    $stid = oci_parse($conn, "INSERT INTO TB100442_MAIL_BACKUP (
      SELECT * FROM (
       SELECT * FROM TB100442_MAIL WHERE 
        DATA_INSERCAO <= TO_DATE(SYSDATE-{$dias}) AND 
        ROWNUM <= {$linhas} 
        ORDER BY ID_MAIL DESC 
      ) 
     )" 
    ); 

    $r = oci_execute($stid, OCI_NO_AUTO_COMMIT); 
    if (!$r) { 
     $e = oci_error($stid); 
     array_push($erro, htmlentities($e['message'] . '. Linha: ' . __LINE__)); 
    } 

    // Prepara o sql de exclusao 
    $stid = oci_parse($conn, "DELETE FROM TB100442_MAIL WHERE ID_MAIL IN (
      SELECT ID_MAIL FROM (
       SELECT ID_MAIL FROM TB100442_MAIL WHERE 
        DATA_INSERCAO <= TO_DATE(SYSDATE-{$dias}) 
        AND ROWNUM <= {$linhas} 
        ORDER BY ID_MAIL DESC 
      ) 
     )" 
    ); 

    $r = oci_execute($stid, OCI_NO_AUTO_COMMIT); 
    if (!$r) { 
     $e = oci_error($stid); 
     array_push($erro, htmlentities($e['message'] . '. Linha: ' . __LINE__)); 

     // Rollback das mudancas em ambas as tabelas 
     oci_rollback($conn); 
    } 

    // Commita as mudancas em ambas as tabelas 
    $r = oci_commit($conn); 
    if (!r) { 
     $e = oci_error($conn); 
     array_push($erro, htmlentities($e['message'] . '. Linha: ' . __LINE__)); 
    } 

    echo '<pre>'; 
    print_r($erro); 
    die; 
} 
+0

如果我正確的翻譯錯誤,你已經違反了唯一鍵約束的地方,可能是一個主鍵。 – 2014-09-02 19:06:29

+0

正確@MarcB。第一個查詢違反了完整性約束,所以我不希望第二個查詢被執行。 – bferronato 2014-09-02 19:19:22

+0

您的第二個查詢不在'if(!$ r)'內,因此無論第一個查詢如何結果,您都嘗試運行第二個查詢。 – 2014-09-02 19:20:54

回答

0

正確的代碼:

public function minimizarSGMail() 
{ 
    $conn = oci_connect(IC::get('database.username'), IC::get('database.password'), IC::get('database.tns')); 
    $linhas = 5; 
    $dias = 90; 
    $return = array(); 

    // Prepara o sql de insert 
    $insert = oci_parse($conn, "INSERT INTO TB100442_MAIL_BACKUP (
      SELECT * FROM (
       SELECT * FROM TB100442_MAIL WHERE 
       DATA_INSERCAO <= TO_DATE(SYSDATE-{$dias}) AND 
       ROWNUM <= {$linhas} 
       ORDER BY ID_MAIL DESC 
      ) 
     )" 
    ); 

    // Prepara o sql de exclusao 
    $delete = oci_parse($conn, "DELETE FROM TB100442_MAIL WHERE ID_MAIL IN (
      SELECT ID_MAIL FROM (
       SELECT ID_MAIL FROM TB100442_MAIL WHERE 
        DATA_INSERCAO <= TO_DATE(SYSDATE-{$dias}) 
        AND ROWNUM <= {$linhas} 
        ORDER BY ID_MAIL DESC 
      ) 
     )" 
    ); 

    // Executa o sql de INSERT, sem commit 
    if(oci_execute($insert, OCI_NO_AUTO_COMMIT)) { 

     // Executa o sql de DELETE, sem commit 
     if(!oci_execute($delete, OCI_NO_AUTO_COMMIT)) { 

      $e = oci_error($delete); 
      array_push($return, htmlentities($e['message'] . '. Linha: ' . __LINE__)); 
     } 
    } else { 

     $e = oci_error($insert); 
     array_push($return, htmlentities($e['message'] . '. Linha: ' . __LINE__)); 
    } 

    // Realiza o rollback dos sqls caso haja erro 
    if(count($return) > 0) { 
     oci_rollback($conn); 
    } 

    // Commita as transacoes 
    if(!oci_commit($conn)) { 
     $e = oci_error($conn); 
     array_push($return, htmlentities($e['message'] . '. Linha: ' . __LINE__)); 
    } 

    oci_free_statement($insert); 
    oci_free_statement($delete); 
    oci_close($conn); 

    return $return; 

}