Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Plsql 为什么我的光标不能正常工作?_Plsql_Cursor_Procedure - Fatal编程技术网

Plsql 为什么我的光标不能正常工作?

Plsql 为什么我的光标不能正常工作?,plsql,cursor,procedure,Plsql,Cursor,Procedure,我设置了一个游标来获取过程结果中的多行。但是,生成以下错误消息似乎不起作用: “01422.00000-“精确提取返回的行数超过请求的行数” *原因:精确提取中指定的行数小于返回的行数。 *操作:重写查询或更改请求的行数“ 代码的其他部分没有问题,正如我在只有一条记录时尝试的那样,它运行良好。但当有多条记录时,我的光标似乎不起作用。为什么呢 set serveroutput on declare get_term scores.term%type; get_sectno score

我设置了一个游标来获取过程结果中的多行。但是,生成以下错误消息似乎不起作用: “01422.00000-“精确提取返回的行数超过请求的行数” *原因:精确提取中指定的行数小于返回的行数。 *操作:重写查询或更改请求的行数“

代码的其他部分没有问题,正如我在只有一条记录时尝试的那样,它运行良好。但当有多条记录时,我的光标似乎不起作用。为什么呢

set serveroutput on

declare
   get_term scores.term%type;
   get_sectno scores.sectno%type;
   get_sid scores.sid%type;
   get_score scores.points%type;
   status boolean;

   procedure total_score (aterm in out scores.term%type,
                 asectno in out scores.sectno%type,
                 asid out scores.sid%type,
                 ascore out scores.points%type,
           status out boolean)
   is
   cursor find is 
      select scores.term, scores.sectno, sid, sum(points/maxpoints*weight)
      from scores, components
      where scores.term=components.term
      and scores.sectno=components.sectno
      group by scores.term, scores.sectno, sid;
   find_rec find%rowtype;   
   begin
      open find;
      fetch find into find_rec;
      while find%found loop
         select scores.term, scores.sectno, sid, sum(points/maxpoints*weight)
         into aterm, asectno, asid, ascore
         from scores, components
         where scores.term=components.term
         and scores.term=aterm
         and scores.sectno=components.sectno
         and scores.sectno=asectno
         and scores.compname=components.compname
         group by scores.term, scores.sectno, sid;
         status:=true;
         fetch find into find_rec;
      end loop;
      close find;
   exception
      when no_data_found then
         status:=false;
   end;
begin
   get_term:='F12';
   get_sectno:='1031';
   total_score (get_term, get_sectno, get_sid, get_score, status);
   if (status) then
      dbms_output.put_line(get_term||' '||get_sectno||' '||get_sid||' '||get_score);
   else
      dbms_output.put_line('Record not found.');
   end if;
end;

我想重写如下:

open find;
loop
 fetch find into find_rec;
 Exit when find%NOTFOUND;
...
end loop;
close find;
但是,如果不在内部选择中使用其值,为什么要打开此光标? 但是,我认为产生错误是因为游标中的select在一次或多次迭代中返回两行或多行。 有关更多信息,请参见,例如。再见,伊戈尔

更新:

CREATE TABLE SCORES(SID INTEGER, TERM VARCHAR2(10), SECTNO VARCHAR2(10), COMPNAME VARCHAR2(50));
CREATE TABLE COMPONENTS(TERM VARCHAR2(10), SECTNO VARCHAR2(10), COMPNAME VARCHAR2(50), POINTS INTEGER, MAXPOINTS INTEGER, WEIGHT INTEGER);



INSERT ALL
INTO SCORES VALUES(1,'AAA', 'BBB', 'CCC')
INTO SCORES VALUES(5,'AAA', 'BBB', 'CCC')
INTO SCORES VALUES(2,'DDD', 'EEE', 'FFF')
INTO SCORES VALUES(3,'GGG', 'HHH', 'III')
SELECT * FROM DUAL;


INSERT ALL
INTO COMPONENTS VALUES('AAA', 'BBB', 'CCC', 1, 2, 3)
INTO COMPONENTS VALUES('DDD', 'EEE', 'FFF', 4, 5, 6)
INTO COMPONENTS VALUES('GGG', 'HHH', 'III', 7, 8, 9)
SELECT * FROM DUAL;

COMMIT;



CREATE OR REPLACE PROCEDURE TOTAL_SCORE (ATERM in OUT SCORES.TERM%type,
                 ASECTNO in OUT SCORES.SECTNO%type) AS
 cursor find (cpAterm VARCHAR2, cpAsectno VARCHAR2) is 
      select scores.term, scores.sectno, sid, sum(points/maxpoints*weight) AS SUM_SCORE
         from scores RIGHT JOIN components ON
         scores.term=components.term
         and scores.sectno=components.sectno
         and scores.compname=components.compname
         WHERE
          scores.term=cpAterm
          AND scores.sectno=cpAsectno
         group by scores.term, scores.sectno, sid;
   find_rec find%rowtype; 

   counter INTEGER:=0;

BEGIN
 open find(ATERM, ASECTNO);
 LOOP
       fetch find into find_rec;
      exit when find%notfound;
      --DBMS_OUTPUT.PUT_LINE(find_rec.TERM||' '||find_rec.sectno||' '||find_rec.SID||' '||find_rec.SUM_SCORE);
      if (find_rec.term IS NOT NULL) then
      dbms_output.put_line(find_rec.TERM||' '||find_rec.sectno||' '||find_rec.SID||' '||find_rec.SUM_SCORE);
      counter:=counter+1;
      END IF;
      end loop;
      close find;
      if counter = 0 then
      dbms_output.put_line('NO DATA FOUND FOR: ' || ATERM || ', ' || ASECTNO);
      end if;

END;
/

SET SERVEROUTPUT ON
DECLARE
 get_term VARCHAR2(10);
 get_sectno VARCHAR2(10);
begin
   get_term:='AAA';
   get_sectno:='BBB';
   total_score (get_term, get_sectno);
  END;
/

DROP TABLE SCORES;
DROP TABLE COMPONENTS;

我想重写如下:

open find;
loop
 fetch find into find_rec;
 Exit when find%NOTFOUND;
...
end loop;
close find;
但是,如果不在内部选择中使用其值,为什么要打开此光标? 但是,我认为产生错误是因为游标中的select在一次或多次迭代中返回两行或多行。 有关更多信息,请参见,例如。再见,伊戈尔

更新:

CREATE TABLE SCORES(SID INTEGER, TERM VARCHAR2(10), SECTNO VARCHAR2(10), COMPNAME VARCHAR2(50));
CREATE TABLE COMPONENTS(TERM VARCHAR2(10), SECTNO VARCHAR2(10), COMPNAME VARCHAR2(50), POINTS INTEGER, MAXPOINTS INTEGER, WEIGHT INTEGER);



INSERT ALL
INTO SCORES VALUES(1,'AAA', 'BBB', 'CCC')
INTO SCORES VALUES(5,'AAA', 'BBB', 'CCC')
INTO SCORES VALUES(2,'DDD', 'EEE', 'FFF')
INTO SCORES VALUES(3,'GGG', 'HHH', 'III')
SELECT * FROM DUAL;


INSERT ALL
INTO COMPONENTS VALUES('AAA', 'BBB', 'CCC', 1, 2, 3)
INTO COMPONENTS VALUES('DDD', 'EEE', 'FFF', 4, 5, 6)
INTO COMPONENTS VALUES('GGG', 'HHH', 'III', 7, 8, 9)
SELECT * FROM DUAL;

COMMIT;



CREATE OR REPLACE PROCEDURE TOTAL_SCORE (ATERM in OUT SCORES.TERM%type,
                 ASECTNO in OUT SCORES.SECTNO%type) AS
 cursor find (cpAterm VARCHAR2, cpAsectno VARCHAR2) is 
      select scores.term, scores.sectno, sid, sum(points/maxpoints*weight) AS SUM_SCORE
         from scores RIGHT JOIN components ON
         scores.term=components.term
         and scores.sectno=components.sectno
         and scores.compname=components.compname
         WHERE
          scores.term=cpAterm
          AND scores.sectno=cpAsectno
         group by scores.term, scores.sectno, sid;
   find_rec find%rowtype; 

   counter INTEGER:=0;

BEGIN
 open find(ATERM, ASECTNO);
 LOOP
       fetch find into find_rec;
      exit when find%notfound;
      --DBMS_OUTPUT.PUT_LINE(find_rec.TERM||' '||find_rec.sectno||' '||find_rec.SID||' '||find_rec.SUM_SCORE);
      if (find_rec.term IS NOT NULL) then
      dbms_output.put_line(find_rec.TERM||' '||find_rec.sectno||' '||find_rec.SID||' '||find_rec.SUM_SCORE);
      counter:=counter+1;
      END IF;
      end loop;
      close find;
      if counter = 0 then
      dbms_output.put_line('NO DATA FOUND FOR: ' || ATERM || ', ' || ASECTNO);
      end if;

END;
/

SET SERVEROUTPUT ON
DECLARE
 get_term VARCHAR2(10);
 get_sectno VARCHAR2(10);
begin
   get_term:='AAA';
   get_sectno:='BBB';
   total_score (get_term, get_sectno);
  END;
/

DROP TABLE SCORES;
DROP TABLE COMPONENTS;

我试图用你的方法重写代码,但也不起作用。“光标内的select在一次或多次迭代中返回两行或多行”是什么意思?光标不是用来处理多行吗?在光标的每次迭代中,select必须只返回一行,以允许设置变量:变量-->值。因此,在迭代中,如果select返回两条记录,那么在aterm、asectno、asid、ascore变量中插入什么值?第一行的值是多少?第二行的值是多少?我明白。但在我的代码中会发生什么呢?你是说我的游标定义不正确还是我没有正确使用它?我如何解决这个问题?谢谢。执行select:我认为它将检索两条或更多记录;如果是这样,例如,使用光标值进行过滤,以便每次迭代仅检索一行;例如:WHERE scores.term=find_rec.something。。。最后,我建议在from子句中使用join(从a.id=b.id等上的内部join b)。我想我正在使用光标访问多个记录。是,select语句将返回多行记录。但光标不是会从一行记录移动到另一行来处理所有记录吗?这不是循环的目的吗?我试图用你的方法重写代码,但它也不起作用。“光标内的select在一次或多次迭代中返回两行或多行”是什么意思?光标不是用来处理多行吗?在光标的每次迭代中,select必须只返回一行,以允许设置变量:变量-->值。因此,在迭代中,如果select返回两条记录,那么在aterm、asectno、asid、ascore变量中插入什么值?第一行的值是多少?第二行的值是多少?我明白。但在我的代码中会发生什么呢?你是说我的游标定义不正确还是我没有正确使用它?我如何解决这个问题?谢谢。执行select:我认为它将检索两条或更多记录;如果是这样,例如,使用光标值进行过滤,以便每次迭代仅检索一行;例如:WHERE scores.term=find_rec.something。。。最后,我建议在from子句中使用join(从a.id=b.id等上的内部join b)。我想我正在使用光标访问多个记录。是,select语句将返回多行记录。但光标不是会从一行记录移动到另一行来处理所有记录吗?这不是循环的目的吗?