在PL/SQL块中存储选择结果并使用循环进行测试

在PL/SQL块中存储选择结果并使用循环进行测试,sql,oracle,Sql,Oracle,我想将查询的结果集存储到某个临时位置(听说过游标),然后使用循环根据一个值测试每一列。我试过了 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; / 对不起,我把你弄糊涂了。我的要求是

我想将查询的结果集存储到某个临时位置(听说过游标),然后使用循环根据一个值测试每一列。我试过了

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列,并且我正在寻找一种替代方法,在该方法中,我可以测试select查询的每个记录,以检查获取的任何记录中的任何列是否为0


很抱歉,我的问题没有正确发布。

这里有一个模板,我认为它将帮助您:

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;

以下是一个模板,我认为它将帮助您:

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;

游标不存储结果,它实际上是一个指针,可以让您在结果上进行迭代(如@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'
值看起来像是将日期存储为字符串。您应该将日期存储为实际日期。(如果列是日期,那么您依赖于隐式转换,这也不是一个好主意……

光标不存储结果,它实际上是一个指针,可以让您在结果上进行迭代(如@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'
值看起来像是将日期存储为字符串。您应该将日期存储为实际日期。(如果列是日期,则依赖隐式转换,这也不是一个好主意…

这里有一个非常简单的方法来循环查询结果:

BEGIN
  FOR rec IN (select col1, col2 from mytable where column = '20190103') LOOP
    IF rec.col1 > rec.col2 THEN
      ...
    END IF;
  END LOOP;
END;

下面是一种非常简单的循环查询结果的方法:

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的表中每个字段的记录数。 用你的表名替换我的表名

    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的表中每个字段的记录数。 用你的表名替换我的表名

    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";

为什么不使用一个
UPDATE
语句和一个
WHERE
子句来定义应该更新哪些行?我不明白在这种情况下是否需要游标如果您正在测试一个条件,为什么不作为查询的一部分而不是在循环中这样做呢?您将如何处理满足和不满足条件的行?你可能在找,但不清楚。。。如果只是计算与条件匹配的行数,那么可能只需要一个简单的聚合
count(*)
,它根本不需要PL/SQL。为什么不使用一个
UPDATE
语句和一个
WHERE
子句来定义应该更新哪些行?我不明白在这种情况下是否需要游标如果您正在测试一个条件,为什么不作为查询的一部分而不是在循环中这样做呢?您将如何处理满足和不满足条件的行?你可能在找,但不清楚。。。如果您只是计算与条件匹配的行数,那么您可能只需要一个简单的聚合
count(*)
,它根本不需要PL/SQL。很抱歉,我把您弄糊涂了。我的要求是检查一组记录的任何列是否包含0,如果是,我需要递增以获得任何列中包含0的行数。我可以查询它,但我必须键入所有200列,并且我正在寻找一种替代方法,在该方法中,我可以测试select查询的每个记录,以检查获取的任何记录中的任何列是否为0。很抱歉没有正确发布我的问题。您仍然需要键入所有列名,以便在循环中逐个检查。或者您可以使用
dbms\u sql
来实现自动化,但这可能会使事情过于复杂。使用静态SQL查询或PL/SQL块,您可以通过对数据字典的查询生成列列表,以节省您在物理上键入所有列(如果这是您唯一的异议)。但是你仍然需要确定哪些列要包括,或者如果列表较短的话,可能要排除哪些列。如果我把你弄糊涂了,我很抱歉。我的要求是检查一组记录的任何列是否包含0,如果是,我需要递增以获得任何列中包含0的行数。我可以查询它,但我必须键入所有200列,并且我正在寻找一种替代方法,在该方法中,我可以测试select查询的每个记录,以检查获取的任何记录中的任何列是否为0。很抱歉没有正确发布我的问题。您仍然需要键入所有列名,以便在循环中逐个检查。或者您可以使用
dbms\u sql
来实现自动化,但这可能会使事情过于复杂。使用静态SQL查询或PL/SQL块,您可以通过对数据字典的查询生成列列表,以节省您在物理上键入所有列(如果这是您唯一的异议)。但您仍然需要确定要包括哪些列—或者