Russian Qt Forum
Ноябрь 24, 2024, 08:37 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: получить id вставленной строки  (Прочитано 11566 раз)
RomiX
Гость
« : Апрель 09, 2011, 14:48 »

выполняю примерно такой запрос INSERT INTO `table` (`name`) VALUES('No name')
как мне получить id который был присвоен только что вставленной записи?
например phpMyAdmin после записи пишет что то вроде:Inserted row id: 14
база MySql
Записан
Nimbus
Гость
« Ответ #1 : Апрель 09, 2011, 15:12 »

SELECT LAST_INSERT_ID();
Записан
RomiX
Гость
« Ответ #2 : Апрель 09, 2011, 15:25 »

а тоесть id сам не возвращается, прост о не хотел делать дополнительных запросов, спс
Записан
NicK
Гость
« Ответ #3 : Апрель 09, 2011, 15:38 »

Код
C++ (Qt)
...
QSqlQuery query(db);
...
if query.exec("INSERT INTO `table` (`name`) VALUES('No name')"){
      qDebug()<<"last inserted id:"<<query.lastInsertId().toString();
};
 
Записан
Nimbus
Гость
« Ответ #4 : Апрель 09, 2011, 15:53 »

а тоесть id сам не возвращается, прост о не хотел делать дополнительных запросов, спс
Фактически, запрос всё равно делается. Вот в Оракле для этого не нужно делать дополнительного запроса Улыбающийся
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #5 : Апрель 09, 2011, 17:18 »

Для данных целей в FB использовал такой метод

1) сам дергал генератор для получения ID
2) использовал это полученное ID для вставляемой строки, тем самым уже зная его

Все это в связи с тем что в пределах выполняемой транзакции нельзя было увидеть ID вставленной строки до подтверждения или отмены ее.

Может быть еще как то returning может помочь (сам не использовал - была дискуссия в теме про альтернативный драйвер Qt FB).
Записан
johnpion
Гость
« Ответ #6 : Апрель 12, 2011, 15:46 »

В SQLLite есть полезная системныя таблица для этих целей.
Код:
SELECT seq FROM sqlite_sequence WHERE name = 'actions'
Записан
asvil
Гость
« Ответ #7 : Апрель 12, 2011, 15:57 »

Как рад, что пользуюсь Postgres. Все ваши БД отстают по удобству использования.

Код:
insert into table values a, b, c, d returning *

В очень мною ненавидимом оракле 10 приходиться делать связывание OUT переменных, что как оказалось чревато сегфолтом, если под данную переменную не выделить память, хотя бы вот так QVariant(QString(' ', 10)). Первичный ключ текстовый в данном случае.
В целом оракл оставляет желать лучшего в плане удоства программирования. Взять хотя бы невозможность навески одного триггера на несколько таблиц. Или невозможность модификации сиквенса. Кто там из менеджеров/инженеров вообще додумался до такой хрени, а?


Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #8 : Апрель 12, 2011, 16:51 »

Цитировать
Как рад, что пользуюсь Postgres. Все ваши БД отстают по удобству использования.

В Firebird 2.1 такой запрос вполне корректно работает и возвращает значение вставленного ID
Код:
insert into ACTIVITY(NAME)
values ('0111')
returning ROW_ID
Уверен и во многих других БД это рабоатет, вопрос был в том что returning не поддерживался стандартным драйвером Qt для Interbase/Firebird.

Цитировать
Первичный ключ текстовый в данном случае.
Сомнительное решение

Цитировать
Взять хотя бы невозможность навески одного триггера на несколько таблиц.
Зачем это нужно? Триггеры для отработки эконом. логики все равно для каждой таблицы свои, поля то в таблицах разные. А триггеры формирования пустых ROW_ID или подобные настолько просты, что нет проблем их иметь кадждый на свою таблицу.
Записан
asvil
Гость
« Ответ #9 : Апрель 12, 2011, 17:15 »

Цитировать
insert into ACTIVITY(NAME)
values ('0111')
returning ROW_ID
ROW_ID в данном случае псевдо-колонка? Если да, это костыль. Если это имя столбца, то API firebird client библиотеки возможно непродумано. В постгри клиенте есть одна большая PGresult* PQexec(SQL_STRING); Соответственно Кутешники поняли, что какой бы SQL пользователь не выполнил ему всегда надо отдать QSqlResult пусть даже пустой.

Цитировать
Сомнительное решение
Не спорю. Но даже на int64(простите не знаю имя типа oracle), нужно сделать как минимум QVariant(QVariant::qlonglong) для OUT переменной и только после сделать addBindValue.

Цитировать
Зачем это нужно?
Есть такая занимательная игра у менеджеров, называется "больше велосипедов, хороших и красивых". Задача: самодельная репликация для оракла. Если бы у меня была возможность навесить один большой триггер на все таблицы, я бы в нем используя хм... "интроспекцию" делал insert|update|delete в прилинкованную базу.
Итого: репликация отключается/включается одним большим триггером, который потом для скорости переписывается на сях. У вас тоже можно писать модули на сях?
Ан нет я сейчас буду лепить триггера, много хороших и красивых.

Цитировать
А триггеры формирования пустых ROW_ID....
Вы имеете ввиду автогенерацию значений для первичных и не обязательно ключей?
Сравните

Код:
create table(
   id bigserial;
   name text;
);
Который разворачивается в
Код:
create sequence table_id_seq int64 start 0 end 99..99 increment 1;
create table(
   id int64 default next_val(table_id_seq);
   name text;
);
И вот уже никаких триггеров не нужно для такой задачи.


Кстати как-то увидел:
Код:
if :NEW.id = null then
   select max(id) + 1 into :new.id from table;
end if;
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #10 : Апрель 12, 2011, 23:47 »

Цитировать
ROW_ID в данном случае псевдо-колонка? Если да, это костыль. Если это имя столбца, то API firebird client библиотеки возможно непродумано.
это не псевдо колонка, а обычная колонка, кстати по сути конкретно от FB в Postgre модификатор RETURNING мало чем отличается.
Цитировать
У вас тоже можно писать модули на сях?
FB поддерживает UDF как и многи сервера БД

Цитировать
Вы имеете ввиду автогенерацию значений для первичных и не обязательно ключей?
да
Цитировать
И вот уже никаких триггеров не нужно для такой задачи.
И что это круто?
А такое типа не круто:
Код:
SET TERM ^ ;
CREATE TRIGGER ACTIVITY_BI FOR ACTIVITY ACTIVE
BEFORE INSERT POSITION 0
as
begin
  if (new.row_id is null) then
    new.row_id = gen_id(gen_activity_id,1);
end^
SET TERM ; ^

Я вот например не уверен на 100% что спецописания полей лучше использовать для автогенерации значений, чем триггеры - как минимум одинаково. Преимущество триггеров в их модульности, возможности навесить несколько триггеров и упорядочить их, для спец логики нельзя же вводить новые спец описания на таблицу - например если нельзя удалять запись с ID=1, или со списком ID хранящихся в другой таблице.

Цитировать
Есть такая занимательная игра у менеджеров, называется "больше велосипедов, хороших и красивых".
Это скорее игры умников программистов старающихся выпендриться, перед менеджерами стоят как правило типовые задачи учета и анализа.
Вообще задача триггера для таблицы сработать и выполнить код в момент событий вставки, удаления, обновления записи. Непонятно как для разных таблиц можно использовать в таком случае один код. Но уж если сильно хочется можно написать Хранимую Процедуру, части которой переписаны на Сях и вызывать ее из триггеров заглушек расставленных по таблицам.

А вообще задача кажется весьма надуманной и неконкретной - скорее для писькомерства Postgre с другими БД.
Записан
asvil
Гость
« Ответ #11 : Апрель 13, 2011, 09:48 »

Цитировать
А такое типа не круто:
Дело вкуса. Предпочитаю лениться. Моя крутизна в том, что у меня одна строка делает одну функцию (автоинкремент). Мне не нужна мощность/расширяемость.

Цитировать
Это скорее игры умников программистов...
В том числе. Но речь таки не об этом. Речь действительно о пипиське. У postgre самая большая из открытых программ. И далеко не самая маленькая среди коммерческих баз данных.

Я предпочитаю лениться, а не выпендриваться, соответственно, писать все 78 триггеров на таблицы мне не улыбается никак. А готовая репликация для оракла стоит денег, которых соответственно нет.

Если Вам не сложно, дайте задачу реалистичнее и мы с Вами будем меряться.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #12 : Апрель 13, 2011, 11:15 »

Мне нет никакого интереса меряться, более того я не уверен что postgre не самая крутая БД. Может и самая. Но это не важно. Будет интерессная прибыльная задача с которой не справится FB или по Т.З. нельзя будет его использовать, я буду изучать что-то другое, пока мне это не нужно.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.075 секунд. Запросов: 23.