powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
17 сообщений из 17, страница 1 из 1
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34554613
Paramedic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.


Мигрировал на PostgreSQL с Oracle. Задача: из хранимой процедуры получить набор данных. Дело в том, что я использую одну и ту же хранимку как при вызове из своих exe-клиентов, так и из скриптов на PHP. И переписывать запросы логично в одно месте.

В Oracle я возвращал курсор (cursor) из хранимой процедуры. Благо и компоненты прямого доступа с курсорами умели работать, и у PHP ораклёвый экстеншн это делать умел.

В PostgreSQL курсор тоже вернут не проблема. Только вот мучит вопрос: и что с ним потом делать, с курсором этим? Постгресовый экстеншн с курсором не работает, в сторону PostgresDAC я пока даже не смотрел. Подозреваю, что он тоже не умеет работать с курсорами.

Возникает вопрос: как из хранимки выудить набор данных, чтобы можно было спокойно его использовать из любого места.
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34554693
st_serg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
setof

ps. курсоры в пг работают только в рамках транзакции, т.е.
begin;
юзаем курсор;
commit;
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34554735
domanix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
st_serg курсоры в пг работают только в рамках транзакции
Зачем так категорично? А волшебное слово WITH HOLD ?

Код: plaintext
DECLARE name  CURSOR  WITH HOLD  FOR select ...

При такой декларации есть возможность использовать курсор и вне транзакции.
Физически это происходит так- делается селект - и результат помещается во временный файл - который существует пока открыт курсор. Вне зависимости от транзакции вы можете навигироваться по нему как вперед , так и назад....
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34554850
Thamerlan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
domanixDECLARE name CURSOR WITH HOLD FOR select ...
Насколько я помню, такая конструкция не возможна внутри хранимки.
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34554931
Paramedic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я так понял, что должен написать SetOf Имя_таблицы?

В моём случае у меня нет таблицы. Я выбираю данные из нескольких таблиц, да ещё с использованием объединения (union). Или можно этим SetOf ещё как-нибудь воспользоваться?
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34554977
Thamerlan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ParamedicЯ так понял, что должен написать SetOf Имя_таблицы?
В моём случае у меня нет таблицы. Я выбираю данные из нескольких таблиц, да ещё с использованием объединения (union). Или можно этим SetOf ещё как-нибудь воспользоваться?

Только указывая setof_тип_данных (в вашем случае таблица).
По любому, SETOF не очень хорошее решение в плане перформанса. Результат вернется только после финального RETURN (все промежуточные RETURN NEXT будут храниться в памати).

Всё же очень рекомендую реализацию через refcursor'ы.
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34554988
st_serg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
domanix st_serg курсоры в пг работают только в рамках транзакции
Зачем так категорично? А волшебное слово WITH HOLD ?

Код: plaintext
DECLARE name  CURSOR  WITH HOLD  FOR select ...

При такой декларации есть возможность использовать курсор и вне транзакции.
Физически это происходит так- делается селект - и результат помещается во временный файл - который существует пока открыт курсор. Вне зависимости от транзакции вы можете навигироваться по нему как вперед , так и назад....
мой косяк, про волшебное слово забыл
но с рефкурсорами такой фокус, имхо, все равно не пройдет
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34555081
Paramedic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
курсоры это хорошо, но как получить из него данные? В блоке pl/pgsql с ними всё понятно. А вот как вернуть набор данных?
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34555247
domanix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
BEGIN WORK;

-- Set up a cursor:
DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;

-- Fetch the first 5 rows in the cursor liahona:
FETCH FORWARD  5  FROM liahona;

 code  |          title          | did | date_prod  |   kind   |  len
-------+-------------------------+-----+------------+----------+-------
 BL101 | The Third Man           |  101  |  1949 - 12 - 23  | Drama    |  01 : 44 
 BL102 | The African Queen       |  101  |  1951 - 08 - 11  | Romantic |  01 : 43 
 JL201 | Une Femme est une Femme |  102  |  1961 - 03 - 12  | Romantic |  01 : 25 
 P_301 | Vertigo                 |  103  |  1958 - 11 - 14  | Action   |  02 : 08 
 P_302 | Becket                  |  103  |  1964 - 02 - 03  | Drama    |  02 : 28 

-- Fetch the previous row:
FETCH PRIOR FROM liahona;

 code  |  title  | did | date_prod  |  kind  |  len
-------+---------+-----+------------+--------+-------
 P_301 | Vertigo |  103  |  1958 - 11 - 14  | Action |  02 : 08 

-- Close the cursor and end the transaction:
CLOSE liahona;
COMMIT WORK;

Я ответил на вопрос?
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34555401
Thamerlan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Paramedicкурсоры это хорошо, но как получить из него данные? В блоке pl/pgsql с ними всё понятно. А вот как вернуть набор данных?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
CREATE OR REPLACE FUNCTION fnc_get_data ()
RETURNS REFCURSOR AS
$BODY$
DECLARE
   rc   REFCURSOR;
BEGIN
   OPEN rc FOR
      SELECT *
      FROM   pg_user;

   RETURN rc;
END;
$BODY$
LANGUAGE 'plpgsql';


BEGIN;
SELECT * FROM fnc_get_data (); /* SELECT fnc_get_data (); */

          fnc_get_data
      --------------------
       <unnamed portal  1 >
      ( 1  row)


FETCH FORWARD  5  FROM "<unnamed portal 1>";

       usename  | usesysid | usecreatedb | usesuper | usecatupd |  passwd  | valuntil | useconfig
      ----------+----------+-------------+----------+-----------+----------+----------+-----------
       xc_test  |   1060868  | f           | f        | f         | ******** |          |
       postgres |        10  | t           | t        | t         | ******** |          |
       abc      |     16389  | f           | f        | f         | ******** |          |
       power_qa |     20267  | t           | t        | t         | ******** |          |
       opencms  |     20499  | t           | t        | t         | ******** |          |
      ( 5  rows)

ROLLBACK; /* COMMIT; */
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34555941
Paramedic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
domanix , если и ответил, то я всё равно не понял, как данные попадут за пределы pl/pgsql блока?

Thamerlan , у меня уже давно написана функция, возвращающая курсор. И она его действительно возвращает. И похожий пример есть в доке на PostgrerSQL. И в psql всё работает на ура. Но фишка в том, что мне нужно получить данные не в psql, а на стороне клиента. Вот тут-то у меня и не хватает ума, чтобы догнать -- как?
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34555965
st_serg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
может чтото вроде этого?

pgsql_query("begin")
$res1 = pgsql_query("select func() ")
// получаем имя курсора
$res2 = pgsql_query("fetch all from \"полчученное имя курсора\"")
pgsql_query("commit")
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34555989
Paramedic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну я пробовал вот так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<?php
include_once("../gps_vars.php");
$sql = "begin; select * from gps.tst_func('2007-05-28'::date, 14); fetch all from cur1; commit;";
$res = pg_query($sql);
echo "\$res=".$res."<br><br>";
while ($row = pg_fetch_array($res)) {
	echo $row[ 0 ];
        echo "<br>";
}
pg_free_result($res);
pg_close($link);
?>

Ничего не выводит, хотя должно быть 11 записей. Да, и ещё pg_free_result($res); жалуется, что $res не валидный ресурс. Попробую переписать по строке.
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34556013
Thamerlan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не совсем понимаю в чем проблема?

Ну, напрмер, в Delphi это будет что-то типа:

dbconnection.start_transaction;
query1.sql:='SELECT * FROM fnc_get_data ()';
query1.open;
any_string_var := query1.getvaluebycolumnname('fnc_get_data').asstring;

query1.close;
query1.sql:='FETCH FORWARD 5 FROM "'+some_var+'"';
query1.open;

Ну и далее как обычно с селектом: while not query1.eof do ...

P.s.
За точную правильность кода не ручаюсь, delphi под рукой нет ...
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34556019
Thamerlan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ParamedicНу я пробовал вот так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<?php
include_once("../gps_vars.php");
$sql = "begin; select * from gps.tst_func('2007-05-28'::date, 14); fetch all from cur1; commit;";
$res = pg_query($sql);
echo "\$res=".$res."<br><br>";
while ($row = pg_fetch_array($res)) {
	echo $row[ 0 ];
        echo "<br>";
}
pg_free_result($res);
pg_close($link);
?>

Ничего не выводит, хотя должно быть 11 записей. Да, и ещё pg_free_result($res); жалуется, что $res не валидный ресурс. Попробую переписать по строке.

Ну это точно не правильно.
Во первых что есть cur1?
Во вторых вы закрываете транзакцию коммитом до pg_fetch_array ...
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34556049
Paramedic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cur1 -- это поименованный курсор.

Код: plaintext
1.
2.
declare
  cur1 cursor for select ...
...
Рейтинг: 0 / 0
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
    #34556064
Paramedic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ЙОУ!!!! Благодарю. Оно работает :)

Переписал вот так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
<?php

include_once("../gps_vars.php");

$res = pg_query("begin; select * from gps.tst_func('2007-05-28'::date, 14); fetch all from cur1;");
echo "\$res=".$res."<br><br>";

while ($row = pg_fetch_array($res)) {

	echo $row[ 0 ];
	echo "<br>";

}
pg_free_result($res);
pg_query("commit;");
pg_close($dbconn);

?>

Всем участникам от меня по пиву.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]