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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Хранимые процедуры PostgreSQL  (Прочитано 7218 раз)
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 870


Мы должны приносить пользу людям.


Просмотр профиля
« : Январь 24, 2015, 19:59 »

Коллеги,
подскажите, в какой мере Qt поддерживает хранимые процедуры PostgreSQL?
Нужно получить из хранимой процедуры запись или таблицу. Например, хочется так:
Код:
create table WAnswer
(
  RequestId INTEGER,
  groupId INTEGER,
  error INTEGER,
  errorString varchar(255)
);
CREATE OR REPLACE FUNCTION selAnswer(integer) RETURNS RECORD AS $$
DECLARE
   id  ALIAS FOR $1;
   rec RECORD;
BEGIN
   SELECT * INTO rec from WAnswer WHERE RequestId = id;
   RETURN rec;
END;
$$ LANGUAGE plpgsql;

Код:
QSqlQuery answQuery(db);
answQuery.prepare("SELECT selAnswer(:requestId)");
answQuery.bindValue(":requestId", requestId);
answQuery.exec();

if(answQuery.next()){
    int groupId = answQuery.value(1).toInt();
    ...
}
Не выходит каменный цветок... Не возвращает значения полей записи. Хотя answQuery.next() возвращает true.
С таблицей еще хуже. При вызове такой процедуры:
Код:
CREATE OR REPLACE FUNCTION selGroupFunctions(integer) 
RETURNS TABLE(RequestId_ INTEGER, funId_ INTEGER, enabled_ boolean) AS $$
DECLARE
   id  ALIAS FOR $1;
BEGIN
   RETURN QUERY SELECT RequestId, funId, enabled from WGroupFunctions WHERE RequestId = id;
END;
$$ LANGUAGE plpgsql;
next() возвращает false.
Как это можно сделать встроенными средствами Qt? Или придется использовать libpq?
« Последнее редактирование: Январь 24, 2015, 21:20 от sergek » Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Johnik
Крякер
****
Online Online

Сообщений: 339


Просмотр профиля
« Ответ #1 : Январь 24, 2015, 20:18 »

SELECT selAnswer(:requestId)
Проверять сейчас нечем, но если не ошибаюсь, то синтаксис чуть другой в постгре должен быть:
при селекте из функции, которая возвращает record, должно быть перечисление столбцов:
Код:
SELECT * FROM selAnswer(:requestId) as (col_name_1 type_of_col_1, ..., col_name_N type_of_col_N)
при селекте из функции, которая возвращает table:
Код:
SELECT * FROM selAnswer(:requestId)
Записан
vbv
Чайник
*
Offline Offline

Сообщений: 59


Просмотр профиля
« Ответ #2 : Январь 24, 2015, 20:49 »

Поля нумеруются с 0 а не с 1.
т.о value(0) у вас возвращается одно значение.
Все остальное верно.

И еще в psql  SELECT selAnswer(<тут реальное значение>);
вернет ли чего-то.
Но я думаю, что у Вас next таки возвращает один раз true но ничего не печатается т.к. см. начало моего поста.

И по поводу второго запроса. там таки да нужно вызов функции пихать в предложение from но это Вам уже написали.

PS: Тут вопрос не к QT а к postgresql - читаем мануал по postgresql.
« Последнее редактирование: Январь 24, 2015, 21:07 от vbv » Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 870


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #3 : Январь 24, 2015, 21:06 »

Проверять сейчас нечем, но если не ошибаюсь, то синтаксис чуть другой в постгре должен быть:
Спасибо, добрый человек! Все верно в отношении и record, и table, работает. Более того, работает даже именование полей:
Код:
groupVars.groupId = answQuery.value(answRec.indexOf("groupId")).toInt();
groupVars.error = answQuery.value(answRec.indexOf("error")).toInt();

Поля нумеруются с 0 а не с 1.
Да я знаю, мне первое поле не нужно;))
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
vbv
Чайник
*
Offline Offline

Сообщений: 59


Просмотр профиля
« Ответ #4 : Январь 24, 2015, 21:09 »

Но функция из select всегда возвращает одно значение(поле)!!!
И это иногда бывает нужно, лично сталкивался.
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 870


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #5 : Январь 24, 2015, 21:40 »

Но функция из select всегда возвращает одно значение(поле)!!!
И это иногда бывает нужно, лично сталкивался.
Понял свою ошибку.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 870


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #6 : Январь 24, 2015, 23:51 »

Окончательный вариант с использованием SETOF:
Код:
CREATE FUNCTION selAnswer(integer) RETURNS SETOF WAnswer AS $$
BEGIN
   RETURN QUERY SELECT * from WAnswer WHERE RequestId = $1;
END;
$$ LANGUAGE plpgsql;
Код:
        QSqlQuery answQuery(db);
        answQuery.prepare("SELECT * from selAnswer(:requestId) ");
        answQuery.bindValue(":requestId", requestId);
        answQuery.exec();
        QSqlRecord answRec = answQuery.record();

        if(answQuery.next()){
            groupVars.groupId = answQuery.value(answRec.indexOf("groupId")).toInt();
            groupVars.error = answQuery.value(answRec.indexOf("error")).toInt();
            groupVars.errorString = answQuery.value(answRec.indexOf("errorString")).toString();
            ...
        }
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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