WHILE循环出错:ORA-01422:精确提取返回的请求行数多于请求的行数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WHILE循环出错:ORA-01422:精确提取返回的请求行数多于请求的行数相关的知识,希望对你有一定的参考价值。
我是PL / SQL的新手。我想使用WHILE循环显示COUNTRIES表中country_id和country_name值的country_id,其值范围从51到55。循环将在55完成并显示5个国家。
我得到这个错误。我无法弄清楚出了什么问题。
DECLARE
v_country_id countries.country_id%TYPE;
v_country_name countries.country_name%TYPE;
v_counter NUMBER := 51;
BEGIN
SELECT country_id, country_name INTO v_country_id, v_country_name
FROM countries;
WHILE v_counter <= 55 LOOP
DBMS_OUTPUT.PUT_LINE (v_counter ||' is : '|| v_country_id|| 'Country name is '||v_country_name);
v_counter := v_counter+1;
END LOOP;
END;
您的v_country_id
和v_country_name
变量一次只能包含一个值,对应于一个国家/地区。您试图将所有国家/地区的值选择为这些标量变量,这是造成错误的原因。
您可以使用a cursor for-loop,其中光标查询根据ID范围选择您感兴趣的五个国家/地区:
BEGIN
FOR r_country IN (
SELECT country_id, country_name
FROM countries
WHERE country_id BETWEEN 51 AND 55
ORDER BY country_id
)
LOOP
DBMS_OUTPUT.PUT_LINE ('Country ' || r_country.country_id
|| ' is ' || r_country.country_name);
END LOOP;
END;
/
您还可以选择包含具有这些字段的记录的集合,并在集合上循环以显示输出 - 在填充集合时过滤行,或者在循环时对其进行循环。
使用dbms_output
除了调试之外的任何事情都不是一个好主意,因为它依赖于客户端能够显示它,这并非总是如此。
你当然不需要PL / SQL,你可以自己运行游标查询,但可能这是一个练习......
SELECT 'Country ' || country_id || ' is ' || country_name
FROM countries
WHERE country_id BETWEEN 51 AND 55
ORDER BY country_id;
如果您真的想使用while循环,可以使用显式游标:
DECLARE
v_country_id countries.country_id%TYPE;
v_country_name countries.country_name%TYPE;
v_counter PLS_INTEGER := 1;
CURSOR c_country IS
SELECT country_id, country_name
FROM countries
WHERE country_id >= 51
ORDER BY country_id;
BEGIN
OPEN c_country;
WHILE v_counter <= 5
LOOP
FETCH c_country INTO v_country_id, v_country_name;
-- in case there are fewer than 5 to display
EXIT WHEN c_country%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (v_counter || ': '
|| 'Country ' || v_country_id || ' is ' || v_country_name);
v_counter := v_counter + 1;
END LOOP;
END;
/
或者你可以使用一个集合:
DECLARE
TYPE t_country_rec IS RECORD (
country_id countries.country_id%TYPE,
country_name countries.country_name%TYPE
);
TYPE t_country_tab IS TABLE OF t_country_rec;
v_countries t_country_tab;
v_counter PLS_INTEGER := 1;
BEGIN
SELECT country_id, country_name
BULK COLLECT INTO v_countries
FROM countries
WHERE country_id >= 51
ORDER BY country_id;
WHILE v_counter <= 5
LOOP
DBMS_OUTPUT.PUT_LINE (v_counter || ': '
|| 'Country ' || v_countries(v_counter).country_id
|| ' is ' || v_countries(v_counter).country_name);
v_counter := v_counter + 1;
END LOOP;
END;
/
您也可以使用for
循环中的任何一个,并且可以跳过查询中的过滤器并在循环中执行此操作。
但隐式游标for循环更简单。
我还没有在大学里学习'光标'
如果您不应该使用游标,那么他们可能希望您在循环内执行单行查询,这样效率较低但更接近原始代码; select ... into
在循环内移动,但也得到一个where
子句,只获得与当前计数器值匹配的单行:
DECLARE
v_country_id countries.country_id%TYPE;
v_country_name countries.country_name%TYPE;
v_counter NUMBER := 51;
BEGIN
WHILE v_counter <= 55 LOOP
SELECT country_id,country_name INTO v_country_id, v_country_name
FROM countries
WHERE country_id = v_counter;
DBMS_OUTPUT.PUT_LINE (v_counter ||' is : '|| v_country_id
|| ' Country name is '||v_country_name);
v_counter := v_counter+1;
END LOOP;
END;
/
以上是关于WHILE循环出错:ORA-01422:精确提取返回的请求行数多于请求的行数的主要内容,如果未能解决你的问题,请参考以下文章
Oracle - ORA-01422:精确提取返回的行数超过了请求的行数
获取 ORA-01422 的原因:精确提取返回的行数超过了请求的行数
需要 ORA-01422 的解决方案:精确提取返回的行数超过请求的行数