CakePHP вызывает seq.currval в Oracle, когда последовательности не существует

#oracle #cakephp

#Oracle #cakephp

Вопрос:

При попытке вставить запись в таблицу я получаю ошибку последовательности:

 Query: SELECT my_table_seq.currval FROM dual
Warning (512): SQL Error: ORA-02289: sequence does not exist
  

В этой таблице нет последовательности. Это больше похоже на HABTM. У меня есть таблица:

 CREATE TABLE "MYSCHEMA"."MY_TABLE"
(
    "WORK_ID"   NUMBER NOT NULL ENABLE,
    "ITEM_ID" NUMBER NOT NULL ENABLE,
    CONSTRAINT "MY_TABLE_PK" PRIMARY KEY ("WORK_ID", "ITEM_ID")
)
  

Я вручную добавляю оба идентификатора, используя:

 $this->MyModel->set(array('work_id' => 1, 'item_id' => 2));
$this->MyModel->save();
  

Есть идеи, как предотвратить ошибку? Нужно ли мне просто выполнить запрос вручную $this->MyModel->query() ?

Комментарии:

1. Я не уверен, что понимаю вопрос. Вы спрашиваете, как заставить Oracle избегать выдачи исключения, когда ваш запрос использует недопустимую последовательность? Как заполнить данные в этой таблице, не ссылаясь на последовательность? Что-то еще?

2. Как избежать выдачи ошибки? Можно ли это сделать? Значения отображаются в базе данных нормально.

3. Я все еще не уверен, что понимаю вопрос. Если вы выполняете инструкцию SQL, которая выдает ошибку, поскольку ссылается на недопустимое имя последовательности, очевидный ответ — не выполнять эту инструкцию SQL (или выполнить инструкцию SQL, которая ссылается на допустимое имя последовательности). Но я предполагаю, что вы знаете это и имеете какой-то усложняющий фактор, который мешает вам просто исключить инструкцию SQL…

4. Вы знакомы с CakePHP? Когда вы используете $this->MyModel->save(); , он создает SQL для вас. Я ничего не пишу в SQL, который выдает запрос. Это проблема CakePHP, поскольку она связана с Oracle. Это не проблема Oracle как таковая.

Ответ №1:

CakePHP ожидает, что объединяемая таблица (как часть отношения HABTM) имеет свой собственный первичный ключ.

Смотрите http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM

В вашем случае:

 CREATE TABLE MY_TABLE
(
    ID        NUMBER NOT NULL,
    WORK_ID   NUMBER NOT NULL,
    ITEM_ID   NUMBER NOT NULL,
    CONSTRAINT MY_TABLE_PK PRIMARY KEY (ID),
    CONSTRAINT MY_TABLE_UK UNIQUE (WORK_ID, ITEM_ID)
)
  

И не забудьте добавить последовательность MY_TABLE_SEQ:

 CREATE SEQUENCE MY_TABLE_SEQ;
  

Комментарии:

1. Мне нужна таблица, в которую я могу вводить данные без отдельного идентификатора. Я хочу использовать work_id и item_id в качестве PK.

2. Извините, магия CakePHP просто так не работает. Возможно, вам следует придерживаться уже найденного вами обходного пути.

Ответ №2:

что происходит, так это то, что когда cake вызывает lastinsertid для таблицы oracle, он запрашивает последовательность для этой таблицы. если последовательность не указана, она просто принимает значение $tablename _seq.

что вы можете сделать, так это сообщить cakephp в модели, какую последовательность вы используете для этой таблицы.

 MyModel.php

class MyModel extends AppModel{
//in my case 
//my table name was so long it required a shorter sequence name :D
var $sequence = 'my_table_seq';
...
}