Pergunta

Suppose I have a table abc with columns p_id ,u_id, and comments. I want to fetch the data from this table only if there are multiple rows for a particular p_id value (there is a single row of "junk" data in the table for every p_id that I want to ignore). How can I structure my query so that I can determine whether there are multiple rows for a p_id without fetching the data from the cursor.

Currently, my code looks something like this

Declare
  Cursor pqr is 
  Select p_id,u_id,comments from abc where p_id=123;
Begin

--I want to ignore the results if this query returns 0 or 1 row.
--I only want to process the data if this query returns multiple rows

End;
Foi útil?

Solução

You can add an analytic COUNT to your query so that the number of rows in the result set will be available in each row that you fetch from the cursor

Declare
  Cursor pqr is 
   select p_id,u_id,comments
     from (Select p_id,u_id,comments,count(*) over () cnt
             from abc 
            where p_id=123)
    where cnt > 1;
Begin

The probably doesn't buy you much, if any, performance, however. You're forcing Oracle to materialize the entire result set in order to count the number of rows which is likely to make the code slower. You're also adding another column to every row in the result set which will increase memory usage. And you still have to fetch the first row in order to access the CNT column.

What is the business problem you are trying to solve that requires that you know how many rows are going to be fetched before you fetch all the rows? That isn't something that is commonly needed so perhaps there is a better way to solve whatever problem you're facing.

Outras dicas

Try this. It makes the first column be the count, so execute it, fetch the first row. Column 1 will have the number you need.

WITH 
BASE AS
(
    SELECT SOME_STUFF
    FROM SOME_TABLE
    WHERE SOME_CONDITION
)
SELECT (SELECT COUNT(*) FROM BASE),
       BASE.*
FROM BASE
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top