带有游标参数(LOOP FETCH)和For循环子查询的PL / SQL查询错误

时间:2018-03-16 09:40:48

标签: oracle plsql parameters cursor oracle-apex

我想显示country_id,country_name,region_id,highest_elevation,date_of_independence,population的值 其中highest_elevation> 1000 AND< 1000 AND population> 5000000也是具有独立日的国家。 重要的是,region_id的输出必须> 1。

到目前为止,我已尝试对其进行PL / SQL查询。但是,我发现了错误。我做了2个查询变体。带参数的Cursor使用LOOP和FETCH 带参数的游标也使用子查询和FOR LOOP。

这是子查询的代码:

--pakai subqueries tp gak bisa
v_regid countries.region_id%TYPE;
CURSOR cur_con (pregid NUMBER) IS
SELECT country_id,country_name,region_id,highest_elevation,date_of_independence, population
FROM countries
WHERE region_id = pregid 
AND highest_elevation >1000 AND highest_elevation<1000 AND population >5000000 AND date_of_independence IS NOT NULL;
BEGIN
FOR con_rec IN cur_con (v_regid) LOOP
DBMS_OUTPUT.PUT_LINE ( ' ' );
DBMS_OUTPUT.PUT_LINE ( ' ============================================= ' );
DBMS_OUTPUT.PUT_LINE ( ' ID Negara :  ' || con_rec.country_id );
DBMS_OUTPUT.PUT_LINE ( ' Nama Negara : ' || con_rec.country_name );
DBMS_OUTPUT.PUT_LINE ( ' ID Region : ' || con_rec.region_id );
DBMS_OUTPUT.PUT_LINE ( ' Ketinggian yang tertinggi : ' || con_rec.highest_elevation );
DBMS_OUTPUT.PUT_LINE ( ' Hari kemerdekaan : '|| con_rec.date_of_independence );
DBMS_OUTPUT.PUT_LINE ( ' Populasi : ' ||con_rec.population );
DBMS_OUTPUT.PUT_LINE ( ' ============================================= ' );
DBMS_OUTPUT.PUT_LINE ( ' ' );
END LOOP;
END;

第一次查询的错误:ORA-00900:无效的SQL语句

这里带参数的Cursor的代码使用LOOP和FETCH

--pakai cursor n parameter biasa
DECLARE
v_conid countries.country_id%TYPE;
v_coname countries.country_id%TYPE;
v_regid countries.region_id%TYPE;
v_he countries.highest_elevation%type;
v_doi countries.date_of_independence%TYPE;
v_pop countries.population%TYPE;
CURSOR cur_con (pregid NUMBER) IS
SELECT country_id,country_name,region_id,highest_elevation,date_of_independence, population
FROM countries
WHERE region_id = pregid 
AND highest_elevation >1000 AND highest_elevation<1000 AND population >5000000 AND date_of_independence IS NOT NULL;
reccon cur_con%ROWTYPE;
BEGIN
SELECT country_id,country_name,region_id,highest_elevation,date_of_independence, population INTO v_conid,v_coname,v_regid,v_he,v_doi,v_pop
FROM countries;
OPEN cur_con(v_regid);
LOOP
FETCH cur_con INTO reccon;
EXIT WHEN cur_con%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ( ' ' );
DBMS_OUTPUT.PUT_LINE ( ' ============================================= ' );
DBMS_OUTPUT.PUT_LINE ( ' ID Negara :  ' || reccon.country_id );
DBMS_OUTPUT.PUT_LINE ( ' Nama Negara : ' || reccon.country_name );
DBMS_OUTPUT.PUT_LINE ( ' ID Region : ' || reccon.region_id );
DBMS_OUTPUT.PUT_LINE ( ' Ketinggian yang tertinggi : ' || reccon.highest_elevation );
DBMS_OUTPUT.PUT_LINE ( ' Hari kemerdekaan : '|| reccon.date_of_independence );
DBMS_OUTPUT.PUT_LINE ( ' Populasi : ' ||reccon.population );
DBMS_OUTPUT.PUT_LINE ( ' ============================================= ' );
DBMS_OUTPUT.PUT_LINE ( ' ' );
END LOOP;
CLOSE cur_con;
end;

第二次查询的错误:ORA-01422:精确提取返回的请求行数多于

我的查询有什么问题?请帮帮我

1 个答案:

答案 0 :(得分:1)

您的第二个代码存在问题,但代码1对我来说没问题。查看正确的工作版本:

代码1:

DECLARE
  --pakai subqueries tp gak bisa
  --v_regid countries.region_id%TYPE;

  CURSOR cur_con (pregid NUMBER)
  IS 
    SELECT country_id,
      country_name,
      region_id,
      highest_elevation,
      date_of_independence,
      population
    FROM countries
    WHERE region_id           = pregid
    AND highest_elevation     >1000
    AND highest_elevation     <1000
    AND population            >5000000
    AND date_of_independence IS NOT NULL;
BEGIN
  FOR con_rec IN cur_con (v_regid)--<--Assuming you pass value of v_regid
  LOOP
    DBMS_OUTPUT.PUT_LINE ( ' ' );
    DBMS_OUTPUT.PUT_LINE ( ' ============================================= ' );
    DBMS_OUTPUT.PUT_LINE ( ' ID Negara :  ' || con_rec.country_id );
    DBMS_OUTPUT.PUT_LINE ( ' Nama Negara : ' || con_rec.country_name );
    DBMS_OUTPUT.PUT_LINE ( ' ID Region : ' || con_rec.region_id );
    DBMS_OUTPUT.PUT_LINE ( ' Ketinggian yang tertinggi : ' || con_rec.highest_elevation );
    DBMS_OUTPUT.PUT_LINE ( ' Hari kemerdekaan : '|| con_rec.date_of_independence );
    DBMS_OUTPUT.PUT_LINE ( ' Populasi : ' ||con_rec.population );
    DBMS_OUTPUT.PUT_LINE ( ' ============================================= ' );
    DBMS_OUTPUT.PUT_LINE ( ' ' );
  END LOOP;
END;

代码2: - 无需执行两次选择查询。此外,当您在开始块内执行Select时,没有过滤条件,因此查询将重新执行多行,并尝试将多行分配给单个变量。因此,您会遇到问题:ORA-01422: exact fetch returns more than requested number of rows。见下文

--pakai cursor n parameter biasa
DECLARE 
  CURSOR cur_con (pregid NUMBER)
  IS
    SELECT country_id,
      country_name,
      region_id,
      highest_elevation,
      date_of_independence,
      population
    FROM countries
    WHERE region_id           = pregid
    AND highest_elevation     >1000
    AND highest_elevation     <1000
    AND population            >5000000
    AND date_of_independence IS NOT NULL;

  reccon cur_con%ROWTYPE;
BEGIN 
  OPEN cur_con(v_regid);
  LOOP
    FETCH cur_con INTO reccon;
    EXIT  WHEN cur_con%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE ( ' ' );
    DBMS_OUTPUT.PUT_LINE ( ' ============================================= ' );
    DBMS_OUTPUT.PUT_LINE ( ' ID Negara :  ' || reccon.country_id );
    DBMS_OUTPUT.PUT_LINE ( ' Nama Negara : ' || reccon.country_name );
    DBMS_OUTPUT.PUT_LINE ( ' ID Region : ' || reccon.region_id );
    DBMS_OUTPUT.PUT_LINE ( ' Ketinggian yang tertinggi : ' || reccon.highest_elevation );
    DBMS_OUTPUT.PUT_LINE ( ' Hari kemerdekaan : '|| reccon.date_of_independence );
    DBMS_OUTPUT.PUT_LINE ( ' Populasi : ' ||reccon.population );
    DBMS_OUTPUT.PUT_LINE ( ' ============================================= ' );
    DBMS_OUTPUT.PUT_LINE ( ' ' );
  END LOOP;
  CLOSE cur_con;
END;