Find out the number of rows returned by refcursor?

Started by Karen Hillover 19 years ago6 messagesgeneral
Jump to latest
#1Karen Hill
karen_hill22@yahoo.com

What is the best way to find out the total number of rows returned by
an refcursor? This would allow the client user to know the total
amount of rows as they are using FETCH FORWARD/BACKWARD.

For example let's say that an refcursor has 300 rows. The user fetches
20 at a time. I would like the user to know that there are 300
possible rows.

regards,
karen

#2Karen Hill
karen_hill22@yahoo.com
In reply to: Karen Hill (#1)
Re: Find out the number of rows returned by refcursor?

Karen Hill wrote:

What is the best way to find out the total number of rows returned by
an refcursor? This would allow the client user to know the total
amount of rows as they are using FETCH FORWARD/BACKWARD.

For example let's say that an refcursor has 300 rows. The user fetches
20 at a time. I would like the user to know that there are 300
possible rows.

I probably should re-phrase that question.

CREATE OR REPLACE FUNCTION foobar( refcursor ) RETURNS refcurser AS '
BEGIN
OPEN $1 FOR SELECT * FROM t ORDER by z;
END;
' LANGUAGE 'plpgsql';

BEGIN;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- Is there a way to know the total number of rows the cursor is
capable of traversing without using --count? Perhaps GET DIAGNOSTICS
ROW_COUNT?
SELECT foobar('mycursor');
-- I want to avoid using count(*) for performance reasons. Getting the
total number of rows the cursor --has. I suspect it there is a system
variable that has this information...I just don't know which one it
--is.
SELECT COUNT(*) FROM t;

COMMIT;

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Karen Hill (#2)
Re: Find out the number of rows returned by refcursor?

"Karen Hill" <karen_hill22@yahoo.com> writes:

-- Is there a way to know the total number of rows the cursor is
capable of traversing without using --count?

If you want an accurate count, the only way is to traverse the cursor.
Consider using MOVE FORWARD ALL and noting the rowcount, then MOVE
BACKWARD ALL to reset the cursor (the latter at least should be
reasonably cheap).

If you can settle for a (potentially very inaccurate) estimate, consider
using EXPLAIN on the query and noting the planner's rowcount estimate.

regards, tom lane

#4Karen Hill
karen_hill22@yahoo.com
In reply to: Tom Lane (#3)
Re: Find out the number of rows returned by refcursor?

Tom Lane wrote:

"Karen Hill" <karen_hill22@yahoo.com> writes:

-- Is there a way to know the total number of rows the cursor is
capable of traversing without using --count?

If you want an accurate count, the only way is to traverse the cursor.
Consider using MOVE FORWARD ALL and noting the rowcount, then MOVE
BACKWARD ALL to reset the cursor (the latter at least should be
reasonably cheap).

Cool. Quick question, how does one go about noting the rowcount?
Using the rowcount in get diagnostics or something else?

regards,
karen.

#5Karen Hill
karen_hill22@yahoo.com
In reply to: Karen Hill (#1)
Re: Find out the number of rows returned by refcursor?

Karen Hill wrote:

Tom Lane wrote:

"Karen Hill" <karen_hill22@yahoo.com> writes:

-- Is there a way to know the total number of rows the cursor is
capable of traversing without using --count?

If you want an accurate count, the only way is to traverse the cursor.
Consider using MOVE FORWARD ALL and noting the rowcount, then MOVE
BACKWARD ALL to reset the cursor (the latter at least should be
reasonably cheap).

Cool. Quick question, how does one go about noting the rowcount?
Using the rowcount in get diagnostics or something else?

A "MOVE FORWARD ALL FROM cur;" statement returns "MOVE x". Where x is
the number moved. The result seems to be of a NOTICE type, and I'm not
sure how I can pass that as a result from a pgsql function.

I guess what I'm looking for is this, if it is possible:

CREATE OR REPLACE FUNCTION FOOBAR(refcursor , out refcursor , out
total int4) AS '
BEGIN

OPEN $1 FOR SELECT * FROM t_table ORDER by c_column DESC;
total := (MOVE FORWARD ALL FROM $1);
MOVE BACKWARD ALL FROM $1;
$2 := $1;

END;
' LANGUAGE plpgsql;

Thanks in advance.

Also, is this possible? I would like to be able to plug in the name of
the refcursor returned by the above stored procedure and be able to
fetch data:

CREATE OR REPLACE FUNCTION MOVE(refcursor) RETURNS ROWTYPE AS '
BEGIN
FETCH FORWARD 20 FROM $1;
END;
' LANGUAGE plpgsql;

regards,
karen.

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Karen Hill (#5)
Re: Find out the number of rows returned by refcursor?

"Karen Hill" <karen_hill22@yahoo.com> writes:

Cool. Quick question, how does one go about noting the rowcount?
Using the rowcount in get diagnostics or something else?

A "MOVE FORWARD ALL FROM cur;" statement returns "MOVE x". Where x is
the number moved. The result seems to be of a NOTICE type, and I'm not
sure how I can pass that as a result from a pgsql function.

Um ... sorry, you can't really. I was thinking of doing this from
client-side logic, where that count is normally going to be accessible
as part of the command status. plpgsql has a pretty limited set of
cursor features --- I don't think it lets you get at MOVE ALL at all,
let alone check the number of rows moved over. Can you push the
operation over to the client side?

(We ought to try to improve that situation in future releases, but that
won't help you today.)

regards, tom lane