交易PHP和Oracle

时间:2014-09-02 19:04:21

标签: php oracle transactions

为什么以下代码执行查询排除( DELETE FROM ... )甚至在插入查询中出错?

错误消息:

阵 ([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;
}

1 个答案:

答案 0 :(得分: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;

}