Yii+Oracle: проблема с insert

Различные вопросы по установке и настройке фреймворка, конфигурции веб-сервера и IDE.
Ответить
flash11
Сообщения: 3
Зарегистрирован: 2013.02.13, 12:45

Yii+Oracle: проблема с insert

Сообщение flash11 »

Всем привет.
Получил задачу перевести готовое приложение с MySQL на Oracle. С Oracle никогда не работал, тут же столкнулся с массой проблем.
Но все проблемы постепенно преодолевались, и уже даже стали работать SELECT-ы, но вот с INSERT-ами проблема, затыкаюсь на строчках в COciCommandBuilder:

Код: Выделить всё

if(is_string($table->primaryKey) && ($column=$table->getColumn($table->primaryKey))!==null && $column->type!=='string')
{
    $sql.=' RETURNING '.$column->rawName.' INTO :RETURN_ID';
    $command=$this->getDbConnection()->createCommand($sql);
    $command->bindParam(':RETURN_ID', $this->returnID, PDO::PARAM_INT, 12);
    $table->sequenceName='RETURN_ID';
}
Кто-нибудь может подсказать, как оно должно работать? Если ничего не менять, вылетает Exception:
CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 1400 OCIStmtExecute: ORA-01400: cannot insert NULL into ("MYDB"."USERS"."PASS")
(/tmp/pear/download/PDO_OCI-1.0/oci_statement.c:142). The SQL statement executed was: INSERT INTO users (state, first_name, last_name, middle_name, company_name, sex, lang, gmt, avatar, login, pass) VALUES (:yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6, :yp7, :yp8, :yp9, :yp10) RETURNING id INTO :RETURN_ID. Bound with :RETURN_ID=NULL, :yp0='ACTIVE', :yp1='NULL', :yp2='NULL', :yp3='NULL', :yp4='NULL', :yp5=NULL, :yp6=NULL, :yp7=NULL, :yp8='NULL', :yp9='admin4', :yp10='myhashedpassword'
Если внимательно на него посмотреть, то видно, что в поле pass биндится значение myhashedpassword. Почему вылетает такое исключение - не могу понять.

Если закомментировать длину

Код: Выделить всё

$command->bindParam(':RETURN_ID', $this->returnID, PDO::PARAM_INT/*, 12*/);
то по крайней мере сам INSERT проходит - в таблице появляется запись. Но получаю другой Exception:

Код: Выделить всё

CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 3131 OCIStmtExecute: Error while trying to retrieve text for error ORA-03131
(/tmp/pear/download/PDO_OCI-1.0/oci_statement.c:142). The SQL statement executed was: INSERT INTO users (state, first_name, last_name, middle_name, company_name, sex, lang, gmt, avatar, login, pass) VALUES (:yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6, :yp7, :yp8, :yp9, :yp10) RETURNING id INTO :RETURN_ID. Bound with :RETURN_ID=NULL, :yp0='ACTIVE', :yp1='NULL', :yp2='NULL', :yp3='NULL', :yp4='NULL', :yp5=NULL, :yp6=NULL, :yp7=NULL, :yp8='NULL', :yp9='admin5', :yp10='myhashedpassword'
Как я понимаю, ошибка ORA-03131 как раз и говорит о том, что не указано, какого размера буфер выделять под переменную :RETURN_ID.

Ну и если я вообще убираю блок с :RETURN_ID, разумеется, я не получаю id вновь созданной записи в таблице.

Возможно, кто-нибудь сталкивался с такой проблемой? Получается, что при наличии :RETURN_ID бинды как-то смещаются относительно переменных. Драйвер некорректно работает?

phpinfo:
oci8

OCI8 Support enabled
OCI8 DTrace Support disabled
OCI8 Version 2.0.8
Revision $Id: f04114d4d67cffea4cdc2ed3b7f0229c2caa5016 $
Oracle Run-time Client Library Version 12.1.0.1.0
Oracle Compile-time Instant Client Version 12.1

Directive Local Value Master Value
oci8.connection_class no value no value
oci8.default_prefetch 100 100
oci8.events Off Off
oci8.max_persistent -1 -1
oci8.old_oci_close_semantics Off Off
oci8.persistent_timeout -1 -1
oci8.ping_interval 60 60
oci8.privileged_connect Off Off
oci8.statement_cache_size 20 20

PDO_OCI

PDO Driver for OCI 8 and later enabled
Используется Nginx + php-fpm, php версии 5.4.4
flash11
Сообщения: 3
Зарегистрирован: 2013.02.13, 12:45

Re: Yii+Oracle: проблема с insert

Сообщение flash11 »

Если кому понадобится - нужно заменить строку

Код: Выделить всё

$sql.=' RETURNING '.$column->rawName.' INTO :RETURN_ID';
На

Код: Выделить всё

$sql = 'BEGIN '.$sql.' RETURNING '.$column->rawName.' INTO :RETURN_ID; END;';
Проблема была в том, что Oracle не понимал PL/SQL без обрамления BEGIN/END
vazya
Сообщения: 2
Зарегистрирован: 2017.01.20, 14:58

Re: Yii+Oracle: проблема с insert

Сообщение vazya »

У меня получилось, что проблема крылась в том, что ORACLE не понимал значение ID как NULL. Так как было задано PK.
Пришлось создать триггер который проверяет :new.id

Код: Выделить всё

create or replace trigger my2trigger_insert
  before insert on my2  
  for each row
declare
  -- local variables here
begin
if(:new.id is null)  then
select YII2BASIC_SEQ.NEXTVAL INTO :new.id from dual;
else
  return;
end if;

end my2trigger_insert;
после все заработало
vazya
Сообщения: 2
Зарегистрирован: 2017.01.20, 14:58

Re: Yii+Oracle: проблема с insert

Сообщение vazya »

пришлось создать триггер
create or replace trigger my2trigger_insert
before insert on my2
for each row
declare
-- local variables here
begin
if(:new.id is null) then
select YII2BASIC_SEQ.NEXTVAL INTO :new.id from dual;
else
return;
end if;

end my2trigger_insert;
Ответить