Я пробовал поискать и не нашел ничего, что помогло бы мне.
Обычно я запрашиваю эту базу данных и получаю результаты (~ 4000 строк).
Затем я загружаю эти результаты в массив с oci_fetch_array().
Затем я пытаюсь вставить эти значения в другую базу данных.
foreach ($full_output as $row) {
$counter++;
$sql_values .= "INTO DATA (ID, STARTDATE, CITY) VALUES (".$counter.", TO_DATE('".$row['STARTDATE']."', 'YYYY-MM-DD HH24:MI:SS'), '".$row['CITY']."')\n";
if ($counter % 1000 == 0 || $counter == $numrows) {
// inserts every 1000 values
$sql = "INSERT ALL\n".$sql_values."SELECT * FROM dual";
//function that just parses and executes statement
parse_and_query($conn, $sql);
$sql_values ='';
}
}
function parse_and_query($conn,$sql)
{
$stid = oci_parse($conn, $sql);
if (!$stid) { $e = oci_error($conn); print htmlentities($e['message']); exit; }
$r = oci_execute($stid, OCI_DEFAULT);
if (!$r) { $e = oci_error($stid); echo htmlentities($e['message']); exit; }
return $stid;
}
Это работает нормально, однако на выполнение требуется около 10 минут. Я пробовал использовать bind_by_name, но не могу заставить его работать.
Вы, ребята, знаете какой-нибудь более эффективный способ вставки в oracle? Спасибо.






Общие ответы таковы:
Используйте переменные связывания, иначе вы вызовете много операций синтаксического анализа в БД и не сможете повторно использовать структуры данных.
Избегайте коммитов на каждом INSERT (вы уже это поняли). Делать:
$s = oci_parse($c, 'insert into ptab (pdata) values (:bv)');
oci_bind_by_name($s, ':bv', $v, 20, SQLT_CHR);
foreach ($a as $v) {
$r = oci_execute($s, OCI_NO_AUTO_COMMIT); // Use alias OCI_DEFAULT in older OCI8 versions
}
oci_commit($c);
По возможности используйте oci_bind_array_by_name (). Что-то вроде:
$a = array('abc', 'def', 'ghi', 'jkl');
$s = oci_parse($c, "begin mypkg.myinsproc(:a); end;");
oci_bind_array_by_name($s, ":a", $a, count($a), -1, SQLT_CHR);
oci_execute($s);
(См. Стр.195 в http://www.oracle.com/technetwork/topics/php/underground-php-oracle-manual-098250.html)
Или еще быстрее для больших наборов данных - использовать Python cx_Oracle, Node.js node-oracledb, JDBC или OCI, которые имеют API пакетной вставки, например. https://blogs.oracle.com/opal/efficient-and-scalable-batch-statement-execution-in-python-cx_oracle
Вы вставляете в 3 столбца, поэтому вам нужно 3 переменные привязки.
Спасибо за ответ! Знаете ли вы, могу ли я использовать одну переменную привязки для всего оператора VALUES или каждое значение должно иметь отдельную переменную привязки?