Я использую Oracle oci в PHP. Попытка реализовать запрос вставки для хранения дочерней записи документа / файла (с BLOB для содержимого) и возврата ключа записи для сохранения в родительской записи. Я надеялся, что смогу использовать возвращающее предложение для возврата как дескриптора BLOB (стандартная практика) для хранения содержимого, так и ключа записи для возврата ключа записи (который устанавливается с помощью последовательности и срабатывания триггера при отсутствиизначение передается ключу). Во всяком случае, я получаю сообщение об ошибке для привязки переменной записи ключа записи (запрашивая дескриптор). Я просто пытаюсь сделать слишком много в одном запросе?
Код выглядит следующим образом:
Во-первых, метод построения и отправки вызова вставки файла:
function insert_file($fcontents, $ftype, $fname, $fsize) {
$sql="INSERT INTO ES_FILE (FILE_TYPE,FILE_NAME,FILE_CONTENTS,".
"FILE_SIZE) ".
"VALUES (?, ?, EMPTY_BLOB(), ?)";
$fseq=$this->ora_lob_insert($sql,array($ftype, $fname, $fsize),
'FILE_CONTENTS',$fcontents,'FILE_KEY');
return $fseq;
}
Далее стандартный метод для вставки записей, содержащих BLOB. Передается строка запроса вставки, массив значений переменных связывания, имя столбца BLOB, содержимое BLOB и теперь имя другого столбца, который должен быть возвращен (в конечном счете, как возвращаемое значение метода (если оноЭтот метод был хорошо протестирован, прежде чем я добавил дополнительную функцию дополнительного возвращаемого столбца / значения ...
public function ora_lob_insert($sql,$bindarr=array(),$lobcol='',$lobvar='',$other_retcol='') {
Global $errormess;
$retcol=0;
// $sql must finish "RETURNING {lob_column} INTO :mylob" - Use EMPTY_CLOB() when inserting
if (substr_count($sql,'?') != count($bindarr))
{ // number of ? in query string different to number of values in array
$errormess='Error ora_bind_exec: Mismatch between query markers and bind values array!';
}
$i=0;
$worked=false;
foreach ($bindarr as $bindvar) {
$sql=preg_replace('/\?/',":var${i}", $sql, 1);
$i++;
}
if (!strcmp($other_retcol,'')) {
$sql.=" RETURNING $lobcol INTO :mylob";
} else {
$sql.=" RETURNING $lobcol, $other_retcol INTO :mylob, :retcol";
}
$obf_parse=@oci_parse($this->connect,$sql);
if ($obf_parse === false)
{ // Parse Failed
$errormess='Error ora_lob_insert: Query Parse Failed!';
}
$myLOB = @oci_new_descriptor($this->connect, OCI_D_LOB);
// Bind the returned Oracle LOB locator to the PHP LOB object
@oci_bind_by_name($obf_parse, ":mylob", $myLOB, -1, OCI_B_BLOB);
if (strcmp($other_retcol,'')) {
oci_bind_by_name($obf_parse, ":retcol", $retcol, -1, OCI_B_BLOB);
}
$i=0;
foreach ($bindarr as $bindvar) {
@oci_bind_by_name($obf_parse,":var${i}",$bindarr[$i],-1);
$i++;
}
$list=array();
$obf_exec=@oci_execute($obf_parse,OCI_DEFAULT);
if ($obf_exec === false)
{ // Execute Failed
$errormess='Error ora_lob_insert: Query Execution Failed!'."($sql)";
}
// Now save a value to the LOB
if ( !$myLOB->save($lobvar)) {
// On error, rollback the transaction
oci_rollback($this->connect);
$errormess='Error ora_lob_insert: Failed savin BLOB!';
} else {
// On success, commit the transaction
oci_commit($this->connect);
$worked=true;
}
@oci_free_statement($obf_parse);
if (!strcmp($other_retcol,'')) {
return $worked;
} else {
return $retcol;
}
}
При запуске строка, выполняющая имя oci_bind_by_name для "retcol", даетОшибка PHP и сообщение «Невозможно найти свойство дескриптора ...».
Документация предлагает использовать только дескрипторы для обработки BLOB и FILE.
Я просто ломаю библиотеки oci, пытаясь что-то сделатьслишком сложный?