У меня есть 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