Страница 1 из 1

(INSERT INTO ... SELECT ... RETURNING ...) are not supported

Добавлено: 10 авг 2006, 09:47
mdfv
В нотках написано: Cursor based inserts (INSERT INTO ... SELECT ... RETURNING ...) are not supported.

Собственно говоря можно ли другим легким путем решить эту проблему, не вводя лишних переменных или не делая работу триггера по инкременту генератора?

Суть в том, что надо просто продублировать одну запись в таблице , изменив некоторые полянки, после чего получить ПК новой записи для дальнейших манипуляций.

Здесь селект пишуший в инсерт является singleton-ом.

И будет ли в будущих версиях ФБ предусмотрен RETURNING для данной конструкции; пускай ругался-бы на множественные записи и пропускал одиночные как select into без for?

Добавлено: 10 авг 2006, 09:50
Dimitry Sibiryakov
А ты иди стандартным путем: сначала получай ПК новой записи а потом вставляй его.
hint: в список SELECT можно подставить константу.

Добавлено: 10 авг 2006, 09:58
mdfv
Да так сейчас и делаю.
Только нутро сопротивляется.
С логической точки зрения RETURNING является более
правильным методом, т.к. не требуется переписывать работу триггера, который чисто теоретически может измениться когда-нибудь.

Добавлено: 10 авг 2006, 12:53
kdv
С логической точки зрения RETURNING является более правильным методом
это домыслы.

Добавлено: 10 авг 2006, 13:14
WildSery
Я бы даже сказал, что как раз с логической точки зрения RETURNING неправильно. INSERT c SELECT - это операция над множеством, и только в вашем частном случае это одна запись.

Добавлено: 10 авг 2006, 14:41
mdfv
WildSery писал(а):Я бы даже сказал, что как раз с логической точки зрения RETURNING неправильно. INSERT c SELECT - это операция над множеством, и только в вашем частном случае это одна запись.
если RETURNING стоит, то это автоматически означает, одна запись и программист знает, что и зачем делает.
select pole1 from table into :variable тоже ведь операция над множествоми и работает, а ругается во время выполнения только если несколько записей . Наверное такую ситуацию можно отследить и в инсерте с селектом и если запись одна, то пускай работает как аналог insert () values(), а если много, то пусть также как и в селекте ругается во время выполнения.

Добавлено: 10 авг 2006, 15:01
mdfv
kdv писал(а):это домыслы.
Написать что-то в одном месте 1 раз и вызывать из других мест 100 раз,
лучше чем писать чтото одинаковое 100 раз в каждом месте. И если потребуется это что-то изменить, то лучше сделать это в одном месте,
а не искать глюки по 100 остальным местам.

Добавлено: 10 авг 2006, 15:11
kdv
Написать что-то в одном месте 1 раз и вызывать из других мест 100 раз,
лучше чем писать чтото одинаковое 100 раз в каждом месте.
опять же, домыслы. если пишется процедура, которая будет вызываться отовсюду, то там пофиг returning или еще как.
Если в приложении сам оператор insert/select/returning - то тут гарантий его использования везде и единообразно - нет.

Добавлено: 10 авг 2006, 15:19
CyberMax
RETURNING только в FB 2.0 появился... До этого же жили как-то :wink:

Добавлено: 10 авг 2006, 15:31
mdfv
kdv писал(а): если пишется процедура, которая будет вызываться отовсюду
имелся ввиду триггер и то что его содержимое надо плодить по процедурам.

returning все же не на пустом месте возник, и удобно и меньше
возни в случае изменения кода триггера.

Добавлено: 14 авг 2006, 10:33
eugeney
mdfv писал(а):Да так сейчас и делаю.
Только нутро сопротивляется.
С логической точки зрения RETURNING является более
правильным методом, т.к. не требуется переписывать работу триггера, который чисто теоретически может измениться когда-нибудь.
Используй EXECUTE BLOCK, IIRC RETURNING работает через него.

Добавлено: 14 авг 2006, 11:38
mdfv
eugeney писал(а): Используй EXECUTE BLOCK, IIRC RETURNING работает через него.
Или я чего-то не понял или вы перепутали конструкции...

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

INSERT INTO ... VALUES (...) [RETURNING <column_list> [INTO <variable_list>]]
и

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

EXECUTE BLOCK [ (param datatype = ?, param datatype = ?, ...) ]
[ RETURNS (param datatype, param datatype, ...) }
мне нужнен аналог первой из них.

Добавлено: 14 авг 2006, 12:44
Dimitry Sibiryakov
Я думаю Евгений имел ввиду что-то вроде:

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

EXECUTE BLOCK....
BEGIN
FOR SELECT ...
 BEGIN
  INSERT...
  SUSPEND;
 END;
END

Добавлено: 14 авг 2006, 13:12
mdfv
Тем более непонятно: зачем внутри процедуры ехекут блок...
И как это поможет получить ПК вставленной записи.

Добавлено: 14 авг 2006, 13:49
WildSery
В общем-то, ты нигде не написал, что сиё действие внутри ХП происходит, вот тебе Дмитрий и написал структуру блока для вызова снаружи, чтобы вернул список id.
А раз уж это ХП, вообще непонятно, из-за чего сыр-бор. Всё равно у тебя есть переменная под новый id и её ты дальше используешь для своих нужд. В чём логическая разница, сперва получить id, затем создать запись, или создать запись с возвращением id, не понимаю. С точки зрения объектного программирования разве.... чтобы не хранить значение, а передать сразу в следующую процедуру... но так вроде пока всё равно нельзя сделать.

Добавлено: 14 авг 2006, 13:49
eugeney
mdfv писал(а):Тем более непонятно: зачем внутри процедуры ехекут блок...
И как это поможет получить ПК вставленной записи.
Ты задачу поподробне опиши. тебя не поймеш ты из клиента хочеш получить запрос который вставляет и возвращает данные или в коде процедуры? Если в коде процедуры то тогда "иди стандартным путем: сначала получай ПК новой записи а потом вставляй его".

Если с клиента то тогда мой совет имеет смысл, чтобы на каждый вызов fetch не звать insert. Lkz ghjwtlehs cvsck yt bvttn/


P.s. Вообщето генерировать PK в коде тригерра неправильно.

Добавлено: 14 авг 2006, 13:51
kdv
P.s. Вообщето генерировать PK в коде тригерра неправильно.
правильно, только если значение ПК тебя не интересует (не требуется получать обратно).

Добавлено: 14 авг 2006, 14:39
mdfv
Извиняюсь, что не совсем полностью привел условие примера.
Практически все уже работает по-старинке: ч-з дублирование создания ПК в процедуре.
И данный вопрос имеет скорее теоретический характер.
Ведь если допустим было бы автоинкрементное(не генераторное) поле манипулировать которым нет возможности, то наверняка returning в научили бы работать и селективными одиночными инсертами.

Добавлено: 14 авг 2006, 16:38
CyberMax
mdfv писал(а):Ведь если допустим было бы автоинкрементное(не генераторное) поле манипулировать которым нет возможности, то наверняка returning в научили бы работать и селективными одиночными инсертами.
Если бы у бабушки был [...], она была бы дедушкой. Так эта тема имела чисто теоретический интерес? Автоинкрементных полей нет в стандарте SQL и не будет. Хватит уже жить табличными понятиями.
P.S. Правильно формулируй вопросы. А то зашел сейчас с заднего входа...

Добавлено: 14 авг 2006, 17:05
mdfv
Блин. Не живу я табличными понятиями. А упрощаю все до минимального
уровня, чтоб проще читать без лишней воды, но похоже иногда и этого недостаточно...
И данный вопрос рассматривался скорее с точки зрения программной логики, а не манипуляций с БД.