(INSERT INTO ... SELECT ... RETURNING ...) are not supported
(INSERT INTO ... SELECT ... RETURNING ...) are not supported
В нотках написано: Cursor based inserts (INSERT INTO ... SELECT ... RETURNING ...) are not supported.
Собственно говоря можно ли другим легким путем решить эту проблему, не вводя лишних переменных или не делая работу триггера по инкременту генератора?
Суть в том, что надо просто продублировать одну запись в таблице , изменив некоторые полянки, после чего получить ПК новой записи для дальнейших манипуляций.
Здесь селект пишуший в инсерт является singleton-ом.
И будет ли в будущих версиях ФБ предусмотрен RETURNING для данной конструкции; пускай ругался-бы на множественные записи и пропускал одиночные как select into без for?
Собственно говоря можно ли другим легким путем решить эту проблему, не вводя лишних переменных или не делая работу триггера по инкременту генератора?
Суть в том, что надо просто продублировать одну запись в таблице , изменив некоторые полянки, после чего получить ПК новой записи для дальнейших манипуляций.
Здесь селект пишуший в инсерт является singleton-ом.
И будет ли в будущих версиях ФБ предусмотрен RETURNING для данной конструкции; пускай ругался-бы на множественные записи и пропускал одиночные как select into без for?
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
если RETURNING стоит, то это автоматически означает, одна запись и программист знает, что и зачем делает.WildSery писал(а):Я бы даже сказал, что как раз с логической точки зрения RETURNING неправильно. INSERT c SELECT - это операция над множеством, и только в вашем частном случае это одна запись.
select pole1 from table into :variable тоже ведь операция над множествоми и работает, а ругается во время выполнения только если несколько записей . Наверное такую ситуацию можно отследить и в инсерте с селектом и если запись одна, то пускай работает как аналог insert () values(), а если много, то пусть также как и в селекте ругается во время выполнения.
опять же, домыслы. если пишется процедура, которая будет вызываться отовсюду, то там пофиг returning или еще как.Написать что-то в одном месте 1 раз и вызывать из других мест 100 раз,
лучше чем писать чтото одинаковое 100 раз в каждом месте.
Если в приложении сам оператор insert/select/returning - то тут гарантий его использования везде и единообразно - нет.
Используй EXECUTE BLOCK, IIRC RETURNING работает через него.mdfv писал(а):Да так сейчас и делаю.
Только нутро сопротивляется.
С логической точки зрения RETURNING является более
правильным методом, т.к. не требуется переписывать работу триггера, который чисто теоретически может измениться когда-нибудь.
Или я чего-то не понял или вы перепутали конструкции...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, ...) }
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Я думаю Евгений имел ввиду что-то вроде:
Код: Выделить всё
EXECUTE BLOCK....
BEGIN
FOR SELECT ...
BEGIN
INSERT...
SUSPEND;
END;
END
В общем-то, ты нигде не написал, что сиё действие внутри ХП происходит, вот тебе Дмитрий и написал структуру блока для вызова снаружи, чтобы вернул список id.
А раз уж это ХП, вообще непонятно, из-за чего сыр-бор. Всё равно у тебя есть переменная под новый id и её ты дальше используешь для своих нужд. В чём логическая разница, сперва получить id, затем создать запись, или создать запись с возвращением id, не понимаю. С точки зрения объектного программирования разве.... чтобы не хранить значение, а передать сразу в следующую процедуру... но так вроде пока всё равно нельзя сделать.
А раз уж это ХП, вообще непонятно, из-за чего сыр-бор. Всё равно у тебя есть переменная под новый id и её ты дальше используешь для своих нужд. В чём логическая разница, сперва получить id, затем создать запись, или создать запись с возвращением id, не понимаю. С точки зрения объектного программирования разве.... чтобы не хранить значение, а передать сразу в следующую процедуру... но так вроде пока всё равно нельзя сделать.
Последний раз редактировалось WildSery 14 авг 2006, 13:53, всего редактировалось 1 раз.
Ты задачу поподробне опиши. тебя не поймеш ты из клиента хочеш получить запрос который вставляет и возвращает данные или в коде процедуры? Если в коде процедуры то тогда "иди стандартным путем: сначала получай ПК новой записи а потом вставляй его".mdfv писал(а):Тем более непонятно: зачем внутри процедуры ехекут блок...
И как это поможет получить ПК вставленной записи.
Если с клиента то тогда мой совет имеет смысл, чтобы на каждый вызов fetch не звать insert. Lkz ghjwtlehs cvsck yt bvttn/
P.s. Вообщето генерировать PK в коде тригерра неправильно.
Извиняюсь, что не совсем полностью привел условие примера.
Практически все уже работает по-старинке: ч-з дублирование создания ПК в процедуре.
И данный вопрос имеет скорее теоретический характер.
Ведь если допустим было бы автоинкрементное(не генераторное) поле манипулировать которым нет возможности, то наверняка returning в научили бы работать и селективными одиночными инсертами.
Практически все уже работает по-старинке: ч-з дублирование создания ПК в процедуре.
И данный вопрос имеет скорее теоретический характер.
Ведь если допустим было бы автоинкрементное(не генераторное) поле манипулировать которым нет возможности, то наверняка returning в научили бы работать и селективными одиночными инсертами.
Если бы у бабушки был [...], она была бы дедушкой. Так эта тема имела чисто теоретический интерес? Автоинкрементных полей нет в стандарте SQL и не будет. Хватит уже жить табличными понятиями.mdfv писал(а):Ведь если допустим было бы автоинкрементное(не генераторное) поле манипулировать которым нет возможности, то наверняка returning в научили бы работать и селективными одиночными инсертами.
P.S. Правильно формулируй вопросы. А то зашел сейчас с заднего входа...