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


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

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

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

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

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

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

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

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

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

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

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

При такой декларации есть возможность использовать курсор и вне транзакции.
Физически это происходит так- делается селект - и результат помещается во временный файл - который существует пока открыт курсор. Вне зависимости от транзакции вы можете навигироваться по нему как вперед , так и назад....
мой косяк, про волшебное слово забыл
но с рефкурсорами такой фокус, имхо, все равно не пройдет
...
Рейтинг: 0 / 0
28.05.2007, 13:14
    #34555081
Paramedic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
курсоры это хорошо, но как получить из него данные? В блоке pl/pgsql с ними всё понятно. А вот как вернуть набор данных?
...
Рейтинг: 0 / 0
28.05.2007, 14:08
    #34555247
domanix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
Код: 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
28.05.2007, 14:58
    #34555401
Thamerlan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
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
28.05.2007, 17:17
    #34555941
Paramedic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
domanix , если и ответил, то я всё равно не понял, как данные попадут за пределы pl/pgsql блока?

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

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

Код: 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
28.05.2007, 17:42
    #34556013
Thamerlan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
Не совсем понимаю в чем проблема?

Ну, напрмер, в 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
28.05.2007, 17:45
    #34556019
Thamerlan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
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
28.05.2007, 17:55
    #34556049
Paramedic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли PosgreSQL вернуть из хранимой процедуры набор данных?
cur1 -- это поименованный курсор.

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

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

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


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