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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как работать с хранимой процедурой, которая возвращает таблицу? НЕ решено!  (Прочитано 10912 раз)
havok
Гость
« : Март 17, 2010, 08:16 »

Есть на сервере хранима процедура. Описана так:
Код:
procedure slc_list(p_tr IN OUT T_list, p_n_search_id in integer)
is
...
Где тип T_list - это таблица!!!
Мне нужно вызвать эту процедуру, и результат в TableView записать. Подскажите пожалуйста, недавно начавшему изучать Qt + базы. Улыбающийся
Если использовать:
Код:
    QSqlQuery query;
    QSqlQueryModel *model;

    query.prepare("CALL wfp_list.slc_list(?,?)");
    query.bindValue("p_tr",QSql::InOut);
    query.bindValue("p_n_search_id", n_search_id, QSql::In);

    model->setQuery(query);
получаю ошибку "segmentation fault" ;(
« Последнее редактирование: Март 18, 2010, 06:14 от havok » Записан
BRE
Гость
« Ответ #1 : Март 17, 2010, 09:08 »

получаю ошибку "segmentation fault" ;(
А кто будет объект модели создавать?
Записан
havok
Гость
« Ответ #2 : Март 17, 2010, 09:19 »

получаю ошибку "segmentation fault" ;(
А кто будет объект модели создавать?

Упс! Ну да. Это я добавил. Однако
Код:
    query.prepare("CALL wfp_kl_list.slc_kl_list(?,?)");
    query.bindValue("p_tr",QSql::InOut);
    query.bindValue("p_n_search_id", n_search_id, QSql::In);

    model->setQuery(query);

Не работает. Модель пуста...
Надо ведь по-ходу связать model и возвращаемую процедурой таблицу? Потому что модель у меня не "Select ...", а "Call ...". Было бы Select, тут просто - так как я написал + tableView->setModel(model);
А как к модели привязать QSql::InOut? Или вообще не обязательно к модели? Может можно сразу к TableView?Улыбающийся
В инете по этому поводу инфу не нашёл...
« Последнее редактирование: Март 17, 2010, 09:30 от havok » Записан
Kolobok
Гость
« Ответ #3 : Март 17, 2010, 11:58 »

Код:
query.prepare("CALL wfp_kl_list.slc_kl_list(?,?)");
    query.bindValue("p_tr",QSql::InOut);
    query.bindValue("p_n_search_id", n_search_id, QSql::In);

? != "p_tr"
Если в prepare ?, то пользуйся
Код:
void QSqlQuery::bindValue ( int pos, const QVariant & val, QSql::ParamType paramType = QSql::In )

И в первом bindValue значение забыл
Записан
havok
Гость
« Ответ #4 : Март 17, 2010, 12:14 »

И в первом bindValue значение забыл
А какое (как) там прописать значение??? Там же Sql-ый тип Table у него в процедуре!
« Последнее редактирование: Март 17, 2010, 12:16 от havok » Записан
Kolobok
Гость
« Ответ #5 : Март 17, 2010, 14:41 »

И в первом bindValue значение забыл
А какое (как) там прописать значение??? Там же Sql-ый тип Table у него в процедуре!

У тебя подставляется QSql::InOut, а это точно неправильно.
Записан
havok
Гость
« Ответ #6 : Март 18, 2010, 06:11 »

У тебя подставляется QSql::InOut, а это точно неправильно.

Так а у меня процедура описана как:
Код:
procedure slc_list(p_tr IN OUT T_list, p_n_search_id in integer)
is
...
Таблицы в оракле, в процедуре надо описывать "InOut". Если кто знает, напишите пожалуйста не тО, что у меня неправильно. А как НАДО написать. Если в Qt вообще возможно возвращать таблицы из хранимой процедуры...
Записан
Prm
Гость
« Ответ #7 : Март 22, 2010, 13:44 »

С ораклом не работал, но в MySQL работает следующее:

/*таблица с данными*/
CREATE TABLE IF NOT EXISTS `list_data`
(
    `ID` int(10)         unsigned NOT NULL auto_increment,
    `ID_LIST`           int(10) unsigned NOT NULL,
    `DATA_VALUE`    varchar(255) DEFAULT NULL,
   
    PRIMARY KEY  (`ID`),
    UNIQUE KEY `Index_2` (`ID_LIST`,`DATA_VALUE`),
    CONSTRAINT `FK_LIST_DATA_1` FOREIGN KEY (`ID_LIST`) REFERENCES `list_config` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET='UTF8' COMMENT='Таблица данных для справочников';


/*хранимая процедура в базе данных*/
CREATE PROCEDURE `GET_LIST_DATA`(IN VIN_ID_LIST INT)
BEGIN
        SELECT * FROM list_data
        WHERE ID_LIST=VIN_ID_LIST
        ORDER BY DATA_VALUE;
END;;

//код для получения данных
QSqlQuery query(some_database);

query.exec("CALL GET_LIST_DATA('5');");

В результате выполнения запроса query будет содержать набор данных ID, ID_LIST, DATA_VALUE

Версия QT 4.4.3.


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

Сообщений: 846


Просмотр профиля
« Ответ #8 : Март 22, 2010, 14:40 »

в FB будет работать так

query.exec("select * from GET_LIST_DATA('5');");

то есть процедура подставляется вместо таблицы - также можно передавать параметры и использовать where и т.д.
Записан
havok
Гость
« Ответ #9 : Март 23, 2010, 06:21 »

в FB будет работать так

query.exec("select * from GET_LIST_DATA('5');");

то есть процедура подставляется вместо таблицы - также можно передавать параметры и использовать where и т.д.

Это не то. Это я знаю, но у меня другой случай. У меня процедура не "SELECT..."
Она описана так:
Код:
procedure slc_kl_list(p_tr IN OUT T_kl_list,p_n_search_id in integer)
is
  i         binary_integer := 1;
  v_virzit  wfp_main.r_amatpers;
begin
  for c1 in ( select mat_id, numurs, datums_ieros, mat_status, stadija_kod
              from mat
              where nvl(archive_stat, '0') = '0' and mat_id in (
                    select id
                    from buffer
                    where n_search = p_n_search_id
                )
             )
  loop
    p_tr(i).mat_id      :=c1.mat_id;
    p_tr(i).kl_numurs   :=c1.numurs;
    p_tr(i).ieros       :=c1.datums_ieros;
    p_tr(i).status_kod  :=c1.mat_status;
    p_tr(i).stadija_kod :=c1.stadija_kod;
   
    --napravitel processa
    wfp_main.get_virzitajs(c1.mat_id, v_virzit);
    p_tr(i).iestade_kod := v_virzit.iestade_kod;
    p_tr(i).uzv         := v_virzit.uzv;
    p_tr(i).var         := v_virzit.var;
    p_tr(i).amats       := v_virzit.amats;   
    p_tr(i).kontakt     := v_virzit.kontakt;     
   
    --kvalificacija (spisok statej)
    p_tr(i).last_lem := wfp_main.get_mat_pants(c1.mat_id);

    i:=i+1;
  end loop;
 
exception
  when OTHERS then
    raise_exception(gc_packet,'slc_kl_list');
end;

Мне надо как-то её вызвать и получить таблицу T_kl_list, и её в TableView записать...
Записан
Troglodit
Гость
« Ответ #10 : Март 24, 2010, 11:59 »

это проблема не qt, а СУБД. Нужно написать sql-скрипт который будет возвращать нд из этой переменной.
как вариант (версия для mssql)
declare @p_tr T_kl_list
exec  slc_kl_list(@p_tr,?)
select @p_tr

Нужно смотеть реализацию для оракла, от qt здесь ничего не зависит.
Записан
dio
Гость
« Ответ #11 : Март 30, 2010, 13:10 »

Оберните вашу процедуру в функцию. Например вот так:
Код:
create or replace function get_slc_kl_list(p_n_search_id in integer) RETURN T_kl_list
  PIPELINED IS
v_list T_kl_list;
BEGIN
  slc_kl_list(v_list, p_n_search_id);
  FOR i IN 1 .. v_list.count
  LOOP
    PIPE ROW(v_list(i));
  END LOOP; RETURN;
END;
И делайте из нее select:
Код:
select * from table(get_slc_kl_list(:p_n_search_id));
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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