Как найти количество строк в курсоре

Я хочу найти количество строк в курсоре. Есть ли ключевое слово, которое может помочь? Используя COUNT, мы должны написать запрос. Любая помощь будет оценена.


person Avi    schedule 08.02.2011    source источник
comment
К сожалению, ответ отрицательный, потому что Oracle использует статические курсоры. Итак, не означает ли это, что СУБД каким-то образом знает, сколько строк она должна доставить? В качестве альтернативы, можно ли дешево обработать запрос дважды, один раз для подсчета и второй раз для строк? Без этой информации приложению будет сложнее зарезервировать правильный объем памяти в одном блоке.   -  person Johan Boulé    schedule 17.02.2021
comment
А как насчет прокручиваемых курсоров?   -  person Johan Boulé    schedule 17.02.2021


Ответы (11)


Вы можете использовать %ROWCOUNT атрибут курсора.

e.g:

DECLARE
  CURSOR lcCursor IS
  SELECT *
    FROM DUAL;
BEGIN
  OPEN lcCursor ;
  DBMS_OUTPUT.PUT_LINE(lcCursor%ROWCOUNT);
  CLOSE lcCursor ;
END;
person Chandu    schedule 08.02.2011
comment
Это всегда будет возвращать ноль, потому что не было извлечено ни одной строки. - person Sid Holland; 20.08.2015
comment
Этот ответ показывает, насколько веб-сайт с переполнением стека является таким высококачественным, полностью проверенным контентом. Он умрет после десятилетий коррупции и вздора. - person Johan Boulé; 17.02.2021

cursor_variable.%ROWCOUNT - это решение. Но его значение будет 0, если вы проверите его после открытия. Вам нужно перебрать все записи, чтобы получить общее количество строк. Пример ниже:

DECLARE 
  cur sys_refcursor;
  cur_rec YOUR_TABLE%rowtype;
BEGIN
  OPEN cur FOR
  SELECT * FROM YOUR_TABLE;

  dbms_output.put_line(cur%rowcount);--returning 0

  LOOP
    FETCH cur INTO cur_rec;  
    EXIT WHEN cur%notfound;
    dbms_output.put_line(cur%rowcount);--will return row number beginning with 1
    dbms_output.put_line(cur_rec.SOME_COLUMN);
  END LOOP;

  dbms_output.put_line('Total Rows: ' || cur%rowcount);--here you will get total row count
END;
/
person Brij    schedule 07.01.2016

Вы должны открыть курсор, а затем выбрать и подсчитать каждую строку. Больше ничего работать не будет.

person Oracle McSnackers    schedule 14.03.2012
comment
Это правильный ответ. Курсор не содержит строк, это указатель на каждую выбранную строку. - person Sid Holland; 20.08.2015

Вы также можете использовать BULK COLLECT, чтобы не использовать LOOP,

DECLARE
    CURSOR c 
    IS   SELECT *
           FROM employee;
    TYPE emp_tab IS TABLE OF employee%ROWTYPE INDEX BY BINARY_INTEGER;
    v_emp_tab emp_tab;
BEGIN
    OPEN c;
    FETCH c BULK COLLECT INTO v_emp_tab;
    DBMS_OUTPUT.PUT_LINE(v_emp_tab.COUNT);
    CLOSE c;
END;
/
person eifla001    schedule 11.05.2018
comment
Этот раствор должен быть выше. Он работает, требует меньше строк кода и работает лучше. Я бы предпочел c% rowtype, а не employee% rowtype, так как он более гибкий и позволяет изменять выбранную часть запроса без изменения типа. - person Joost Lambregts; 29.04.2020

Вы можете использовать следующий простой однострочный код для вывода количества курсоров

dbms_output.put_line(TO_CHAR(cur%rowcount));
person sgrpwr    schedule 08.05.2018

Это должно сработать для вас

DECLARE

  CURSOR get_data_ IS 
    SELECT * 
    FROM   table_abc_ 
    WHERE  owner = user_; -- your query
  counter_ NUMBER:= 0;

BEGIN

  FOR data_ IN get_data_ LOOP
    counter_ := counter_ + 1;
  END LOOP;
  dbms_output.put_line (counter_);

END;
person Amila    schedule 06.08.2019

Здесь я пытаюсь подсчитать общее количество клиентов старше 25 лет. Поэтому сначала сохраните результат в курсоре. Затем посчитайте размер курсора внутри функции или в самом начале.

 DECLARE
        cname customer24.cust_name%type;
        count1 integer :=0;
        CURSOR MORETHAN is
        SELECT cust_name
        FROM customer24
        where age>25;   
    BEGIN
        OPEN MORETHAN;
        LOOP
        FETCH MORETHAN into cname;
        count1:=count1+1;
        EXIT WHEN MORETHAN%notfound;
        END LOOP;
       -- dbms_output.put_line(count1);
        dbms_output.put_line(MORETHAN%ROWCOUNT);
        CLOSE MORETHAN;
    END;
person ambakick    schedule 03.10.2018

Существует возможный обходной путь, который может быть полезен / необходим из-за накладных расходов на доступ к серверу базы данных по сети (например, при использовании вызовов Ajax).

Учти это:

CURSOR c_data IS
SELECT per_first_name , null my_person_count
  FROM person
 UNION
SELECT null as per_first_name , count( distinct per_id ) as my_person_count
  FROM person
 order by my_person_count ;

В первой извлеченной строке указано количество записей. Один ДОЛЖЕН добавить определенные выбранные столбцы (использование * не работает), и можно добавить дополнительные фильтры.

person PHdAustin    schedule 29.08.2019

Попробуй это:

print(len(list(cursor)))
person pankaj kushwaha    schedule 25.06.2021

У вас не может быть счетчика курсора в начале. Для этого вам нужно получить полный курсор; это способ получить счетчик курсора.

declare
  cursor c2 is select * from dept;
  var c2%rowtype;
  i number :=0;
begin
  open c2;
  loop
    fetch c2 into var;
    exit when c2%NOTFOUND;
    i: = i+1;
  end loop;
  close c2;
dbms_output.put_line('total records in cursor'||i);
end;
person Community    schedule 11.12.2015
comment
Вы должны объяснить, почему это отвечает на заданный вопрос. - person Nathaniel Ford; 11.12.2015
comment
Один только блок кода не дает хорошего ответа. Пожалуйста, добавьте пояснения. - person Louis Barranqueiro; 12.12.2015

person    schedule
comment
Некоторые комментарии к коду могут помочь исходному постеру понять, как код решает проблему. - person Brent Worden; 13.07.2018