在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块,您可以通过对数据字典的查询生成列列表,以节省您在物理上键入所有列(如果这是您唯一的异议)。但您仍然需要确定要包括哪些列—或者