Как преобразовать PHP-код в пакет Oracle для удаления SQL с помощью ассоциативного массива - PullRequest
1 голос
/ 23 октября 2019

У меня есть PHP-код, который делает удаление где на таблицах. Проблема в том, что эти таблицы становятся очень большими, и запуск операторов delete в oracle будет намного быстрее.

вот мой php-код, который я хочу превратить в пакет Oracle

public function deleteWhere(array $where)  {
        $_where = '';
        $cnt = 0;
        $binds = [];
        foreach ($where as $key => $val) {
            if (in_array ( strtoupper($key), $this->FM_IDS )) {

                if(is_array($val)){

                    $operator = $val[0];
                    $a_val = $val[1];

                    if($a_val === ''){
                        $_where .= " $key is null ";

                    }else if($operator == 'IN'){
                        $str = '';
                        foreach ($a_val as $i => $b_val){
                            $binds[':'.$key.$i] = [$b_val, strlen((string)$b_val), null];
                            $str.=':'.$key.$i.',';
                        }
                        $str = rtrim($str,',');
                        $_where .= " $key $operator ($str) ";

                    }elseif($operator == 'IS NOT'){
                        $_where .= " $key IS NOT NULL OR $key <> '' ";

                    }else {
                        $_where .= " $key $operator :$key ";

                        $binds[":$key"] = [$a_val, strlen((string)$a_val), null];
                    }

                    if ($cnt < count ( $where) - 1) {
                        $_where .= ' AND ';
                    }

                }else{

                    if($val == ''){
                        $_where .= " $key is null ";
                    }else {
                        $_where .= " $key = :$key ";
                    }

                    if ($cnt < count ( $where) - 1) {
                        $_where .= ' AND ';
                    }

                    if($val != ''){
                        $binds[":$key"] = [$val, strlen((string)$val), null];
                    }
                }
            }
            $cnt ++;
        }

        if(empty($this->ccpRW)){
            DbLayer::setupConnections ( false, true );
        }

        // bug fix: remove tailing operator
        $_where = preg_replace('/ AND\s*$/i', '', $_where);
        $_where = preg_replace('/ OR\s*$/i', '', $_where);

        //@TODO select then loop and delete using rowid
        $sql = 'select ROWIDTONCHAR (rowid) row_id from ' . $this->tableName . " WHERE $_where";
        $result = $this->ccpRO->execute($sql, $binds);
        while($row = $this->ccpRO->db_fetch_row($result)){
            $sql = 'DELETE FROM ' . $this->tableName . " WHERE rowid = '{$row['row_id']}'";
            //$this->log->debug($sql);
            $this->ccpRW->execute($sql);
        }

    }

Вот что я имею до сих пор. Я не уверен, как передать ассоциативный массив в Oracle.

PROCEDURE DELETEWHERE (
  O_ERRORCODE OUT NUMBER,
  O_ERRORTEXT OUT VARCHAR2,
  I_TABLENAME IN VARCHAR2
)
AS
BEGIN
  dbms_output.put_line('DELETE WHERE ' || I_TABLENAME);  
  --execute immediate 'truncate table CCP.' || I_TABLENAME;
EXCEPTION
WHEN OTHERS THEN  
  O_ERRORCODE := SQLCODE;
  O_ERRORTEXT := SQLERRM;
END;

END PKGCCP;

PHP-код для пакета выше, у меня есть

$i_table_name = explode(".", $this->tableName)[1];
        $errorcode = null;
        $errortext = '';
        $sql = "BEGIN ".DBUSER.".PKGCCP.DELETEALL(:errorcode, :errortext, :itablename); END;";
        $dbh_rw->parse($sql);
        $result =  $dbh_rw->getStatement();

        oci_bind_by_name($result, ':errorcode', $errorcode, 10, SQLT_INT);
        oci_bind_by_name($result, ':errortext', $errortext, 2000, SQLT_CHR);
        oci_bind_by_name($result, ':itablename', $i_table_name, 100, SQLT_CHR);

        db_query_execute($result);

Я не уверен, как передать ассоциативный массив в пакет и какдля чтения этого массива в oracle.

$where является динамическим, то есть это ключ => значение любого значения столбца таблицы. Примером может быть

$where = ['id'=>'93695']; //example 1
$where = ['id'=>['IN',['93695']];  //example 2
...