Сохранение результата выбора и использование цикла для тестирования в блоке PL / SQL - PullRequest
0 голосов
/ 03 января 2019

Я хочу сохранить результирующий набор запроса во временное местоположение (слышно о курсорах), а затем использовать цикл для проверки каждого столбца на предмет значения. Я пытался

Declare r_rec mytable%ROWTYPE;
BEGIN
select * into r_rec from mytable where column='20190103';
/*IF need to test certain condition for each column.
Then
V_C:=V_C+1;
end if; */

end;
/

Извините, если я вас запутал. Мое требование состоит в том, чтобы проверить, содержит ли какой-либо столбец набора записей 0, если мне нужно увеличить, чтобы получить количество строк, которое имеет 0 в любом столбце. Я могу сделать запрос, но мне нужно будет набрать все 200 столбцов, и я ищу альтернативу, где я могу проверить каждую запись запроса на выборку, чтобы проверить, имеет ли какой-либо столбец в любой выбранной записи значение 0.

Извините, что неправильно опубликовал мой вопрос.

Ответы [ 4 ]

0 голосов
/ 04 января 2019

Я изменил этот ответ из Поиск всех полей во всех таблицах для конкретного значения (Oracle)

чтобы рассчитывать. Он будет считать записи для каждого поля в таблице, которая содержит 0. Замените мое имя таблицы на ваше.

    SELECT count(*),
   SUBSTR (table_name, 1, 30) "Table",
      SUBSTR (column_name, 1, 30) "Column"
    FROM cols,
      TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select '
    || column_name
      || ' from '
      || table_name
      || ' where upper('
     || column_name
     || ') like upper(''%'
     || 0
     || '%'')' ).extract ('ROWSET/ROW/*') ) ) t
     where table_name = 'INVENTORY_LINE'
     group by SUBSTR (table_name, 1, 30) ,
      SUBSTR (column_name, 1, 30) 
   ORDER BY "Table";
0 голосов
/ 03 января 2019

Курсор не хранит результаты, это действительно указатель, позволяющий перебирать результаты (как показывает @Ted в действии). Если вы хотите сохранить результаты в своем блоке PL / SQL, вы можете использовать коллекцию , которую вы можете объявить как тип, соответствующий вашей таблице, чтобы быть близким к вашему однострочному запросу в тип записи; а затем массовый сбор в это:

declare
  type t_tab is table of mytable%ROWTYPE;
  v_tab t_tab;
  v_c pls_integer := 0;
begin
  select *
  bulk collect into v_tab
  from mytable
  where col1='20190103';

  for i in 1..v_tab.count loop
    if v_tab(i).col2 = 'Y' then -- whatever you need to test
      v_c := v_c + 1;
    end if;
  end loop;

  dbms_output.put_line(v_c);
end;
/

Но если вы не делаете что-то еще как со строками, которые совпадают, так и со строками, которые не соответствуют вашему условию, вы можете просто добавить это как тест в основной запрос:

declare
  type t_tab is table of mytable%ROWTYPE;
  v_tab t_tab;
  v_c pls_integer := 0;
begin
  select *
  bulk collect into v_tab
  from mytable
  where col1='20190103'
  and col2='Y'; -- whatever you need to test

  for i in 1..v_tab.count loop
    v_c := v_c + 1;
  end loop;

  dbms_output.put_line(v_c);
end;
/

Если вы подсчитываете только соответствующие строки, вам не нужен курсор или коллекция, просто используйте функцию агрегирования:

declare
  v_c pls_integer;
begin
  select count(*)
  into v_c
  from mytable
  where col1='20190103'
  and col2='Y'; -- whatever you need to test

  dbms_output.put_line(v_c);
end;
/

или не использовать PL / SQL вообще:

select count(*)
from mytable
where col1='20190103'
and col2='Y'; -- whatever you need to test

Кстати, ваше значение '20190103' выглядит так, как будто вы храните дату в виде строки. Вам следует использовать правильный тип данных - сохранять даты как фактические даты. (И если столбец является датой, то вы полагаетесь на неявное преобразование, что тоже не очень хорошая идея ...)

0 голосов
/ 03 января 2019

Вот очень простой способ перебрать результат запроса:

BEGIN
  FOR rec IN (select col1, col2 from mytable where column = '20190103') LOOP
    IF rec.col1 > rec.col2 THEN
      ...
    END IF;
  END LOOP;
END;
0 голосов
/ 03 января 2019

Вот шаблон, который, я думаю, поможет вам:

DECLARE
   cursor c1 is
     select column1, column2 ... etc from mytable where column='20190103';

BEGIN

   FOR r_rec in c1
   LOOP
      if r_rec.column_XYZ = something then
       do_something;
      end if;
   END LOOP;
END;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...