Как получить количество строк, которые выбрал запрос в курсор?

mwolf
Дата: 27.10.2004 16:32:03
Что бы узнать количество строк, которые вернул запрос есть конструкция
SELECT *
FROM some_table;

GET DIAGNOSTICS some_variable = ROW_COUNT;

Но если сделать вот так
DECLARE cur CURSOR FOR
  SELECT *
  FROM some_table;

OPEN cur;

GET DIAGNOSTICS some_variable = ROW_COUNT;
То в some_variable возвращается 0.
Как узнать сколько строк попало в курсор?
MaximZ
Дата: 02.11.2004 19:59:57
может я ошибаюсь, но кажется курсор для того и сделан что бы построчно перелопачивать таблицу. Следовательно туда всегда попадает только одна строка. Даже больше скажу, курсор выбирает таблицу построчно только в одном направлении, вперед. То есть назад по нему пойти нельзя.

На сайта постгреса есть замечательная документация, лучше всех написанных про него книг. Почитайте ее.
mik_s
Дата: 03.11.2004 10:14:51
MaximZ: "может я ошибаюсь, но кажется курсор для того и сделан что бы построчно перелопачивать таблицу. Следовательно туда всегда попадает только одна строка. Даже больше скажу, курсор выбирает таблицу построчно только в одном направлении, вперед. То есть назад по нему пойти нельзя.

На сайта постгреса есть замечательная документация, лучше всех написанных про него книг. Почитайте ее."

:))
Вы ошибаетесь.
Что-то я совсем не встречал подобного в постгресе.
Может Вы ошиблись форумом ( надо было на Oracle )? :))
Курсор может ходить и туда и суда и сколько угодно строк.
На сайта постгреса есть замечательная документация, лучше всех написанных про него книг. Почитайте ее.
MaximZ
Дата: 03.11.2004 12:57:05
можно полюбопытствовать, в какой версии постгреса это реализовано и как?
видимо это пробел в моих знаниях.
Просто заглянул
Дата: 03.11.2004 12:59:09
Чтобы "ходить и туда и сюда сколько угодно строк", курсор должен быть объявлен скроллируемым:

DECLARE cur SCROLL CURSOR FOR
  SELECT *
  FROM some_table;

Потом можно и получить количество: Fetch count into some_variable.
Ясно, что для этого Постгресу придется вычитать весь курсор.

Может быть, я тоже ошибся форумом, и мне надо было на Оракл, но я предпочитаю либо считать количество в процессе получения записей из курсора, либо заранее выполнять select count(*) into some_variable from some_table.
MaximZ
Дата: 03.11.2004 13:14:21
mik_s

Курсор может ходить и туда и суда и сколько угодно строк.


Вот по поводу строк я не согласен. Правилнее сказать не количество строк в курсоре, а количество строк в запросе на основе которго составляется курсор. А сам курсор может указывать только на одну строку одновременно.
Может опрелделить количество строк просто с помощью COUNT(*)?
Или как вариант переместить курсор в конец:
MOVE FORWARD ALL curname;
И как то получить на какой строке стоит курсор.

про перемещение в курсоре признаю свою ошибку. Действительно возможно в любом направлении, и даже вроде как появилась абсолютное позиционирование.
mik_s
Дата: 03.11.2004 15:31:19
2: Просто заглянул: "Чтобы "ходить и туда и сюда сколько угодно строк", курсор должен быть объявлен скроллируемым:" в постгресе курсор скролируемый по умолчанию.
2: MaximZ: Может мы используем разные термины для одного и того же? Что значит "Правилнее сказать не количество строк в курсоре, а количество строк в запросе на основе которго составляется курсор. А сам курсор может указывать только на одну строку одновременно"?
Разве указатель на строку и количество строк это одно и то же?
Или в курсоре бывает другое кол-во строк чем в исходном запросе ( sensitive курсоры в постгресе не поддерживаются )?

2 mwolf: Можно через API, если есть такая возможность. в libpq есть функция для получения кол-ва обработанных строк для запросов (например update, delete, move ). Т.е. сделать MOVE как предлагал MaximZ и увидишь кол-во строк.
кто курсорные процедуры писал?
Дата: 03.11.2004 16:55:45
и чё спорить? про то как двигаться по курсору (MOVE) и брать данные (Fetch), в т.ч. и кучкой записей (count) в руководстве понаписано, а вот как с полями курсора работать? Обновлять чи просто как к им обращаться. Че-то не нашел примеров в справке к PgAdmin. И в форуме. Или надо обязательно PlPgSql а в нем FETCH ... INTO?

Поделились бы. Все интересней бы пошло.
mwolf
Дата: 03.11.2004 17:16:32
Ну блин, мужики, вы даёте!!!
Неделя прошла как запостил и тишина была, а сегодня накидали.
Не ожидал.

Значица так.
Сперва про термИны. В названии поста я действительно немного ошибся. Правильнее его надо было бы назвать "Как получить количество строк, полученные курсором из запроса?". Или...
Ну вобщем то, что надо получить, я расписал в первом посте.

А нужно мне это вот для чего.
Я получаю некоторым, весьма большим, запросом N-ное число строк (от 5 до 30 тыс.). Мне надо выдать одну случайную. Для этого есть ф-ция random(). То есть выполнив
MOVE FORWARD round(RowCount*random()) IN cur;
можно сместиться на нужную запись и фетчить её.
Но!!! Что мне поставить в RowCount? То есть, мне надо знать сколько строк вернул SELECT.
В Оракле есть переменные курсора, откуда можно узнать эту цифру.
В Постгрессе я нашёл нечто подобное (см.первый пост), но он работает только для обычных SELECT/UPDARTE/INSERT, для курсоров выдаёт 0.

2 Просто заглянул
Так я пробовал
Fetch count into some_variable
но отгрёб ошибки, какие не помню. Ща буду пробовать ещё раз.
select count(*) into some_variable from some_table.
так делать не могу. Ибо запрос ОЧЕНЬ большой и большей оптимизации уже не подлежит - вылизан до блеску ;-)

2 mik_s
Через АПИ не получится, так как энто всё находится в ХП.
Про MOVE не понял ничего. Из какого места я всё-таки получу заветную цифру?
Просто заглянул
Дата: 03.11.2004 19:41:38
2 mvolf:

Правильный синтаксис команды я не знаю, а проверить не на чем.
Fetch count from cur into some_variable - возможно, так правильно.

Но я не понял. Вы говорите, что вернуть нужно одну строку, зачем тогда городить все эти курсоры? Генерировать случайное число и выбирать одну строку из нужного запроса не проще?
Этот move forvard ведь не сможет просто волшебным образом сместиться, ему придется перебирать в худшем случае 30 тысяч записей, а в результате нужна только одна.