2014-09-02 86 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; 

}