如何从表中获取一行

时间:2018-08-10 02:40:07

标签: plsql plsqldeveloper cursors database-cursor

我有一个名为> :l GenericFetch > fetch prod :: Int 0 > fetch prod :: Double ...type error... > fetch ap :: Maybe Int Nothing > fetch ap :: Int ...type error... > fetch asum :: Int 10 > fetch asum :: String ... type error: no string in `B` constructor... > 的表。

我想运行一个循环 每次都会从表中获取下一个值。

这是一个PL / SQL程序,我正在用游标执行。 这是我的程序 但是它有很多错误:

stud_ans_sheet

3 个答案:

答案 0 :(得分:1)

这行没有任何意义:

nval:= select seq.nextval from stud_ans_sheet.stud_no;

PL / SQL中没有variable := select ...构造,即使存在stud_ans_sheet.stud_no也不是一个表,因此您无法从其中select进行创建,如果可以仍不清楚您想要什么顺序。

如果您只想将记录属性v_stud.stud_no复制到局部变量nval中,则可以使用:

nval := v_stud.stud_no;

但是接下来的问题是,当您可以直接使用v_stud.stud_no时为什么要完全复制它?

通常最好避免在游标遍历所有游标时使用冗长的声明-打开-获取构造。相反,您可以使用:

for r in (
    select stud_no, ans from stud_ans_sheet
)
loop

我看不到为什么要在循环中重新查询stud_ans_sheet只是为了找回已经存在的同一行。如果这与您的update逻辑有关,那么我就不知道应该怎么做。

代码中的update语句每次都会更新表中的每一行,因为它们没有任何where子句。

在PL / SQL中,if条件由then终止,而不是像某些其他语言一样用括号括起来,例如,

if (str2 = str1) then

可以整理为:

if str2 = str1 then

结构for i in 1..10隐式声明了i,其范围为循环,因此您在顶部声明的其他i是一个不同的变量,未使用。

允许您使用空格以提高可读性,所以

update stud_ans_sheet
set score=corr_ans-wrong_ans*0.25+unattempt_ans
where ...   

写得更清楚

update stud_ans_sheet
set    score = corr_ans - wrong_ans * 0.25 + unattempt_ans
where  ...;    

可能您应该一次只关注一个错误,而不是将整个内容都放在这里进行审查。

答案 1 :(得分:0)

我更改了您的某些代码,请尝试以下操作:

SET SERVEROUTPUT ON;

DECLARE
   ANSWER        VARCHAR (10);
   V_CORR        STUD_ANS_SHEET.CORR_ANS%TYPE;
   V_WRONG       STUD_ANS_SHEET.WRONG_ANS%TYPE;
   V_UNATTEMPT   STUD_ANS_SHEET.UNATTEMPT_ANS%TYPE;
   STR1          VARCHAR (40);
   STR2          VARCHAR (40);
BEGIN
   ANSWER := 'AACCABAABD';

   FOR R_STUD IN (SELECT STUD_NO, ANS
                  FROM STUD_ANS_SHEET)
   LOOP
      V_CORR := 0;--It's better to have only one update
      V_WRONG := 0;
      V_UNATTEMPT := 0;

      FOR I IN 1 .. 10
      LOOP
         STR2 := SUBSTR (R_STUD.ANS, I, 1);
         STR1 := SUBSTR (ANSWER, I, 1);

         IF (STR2 = STR1)
         THEN
            V_CORR := V_CORR + 1;
         ELSIF (STR2 = 'E')
         THEN
            V_UNATTEMPT := V_UNATTEMPT + 1;
         ELSE
            V_WRONG := V_WRONG + 1;
         END IF;
      END LOOP;

      UPDATE STUD_ANS_SHEET
      SET SCORE = V_CORR- V_WRONG* 0.25 + V_UNATTEMPT,
          CORR_ANS = V_CORR,
          WRONG_ANS = V_WRONG,
          UNATTEMPT_ANS = V_UNATTEMPT
      WHERE R_STUD.STUD_NO = STUD_NO;
   END LOOP;

END;
/

答案 2 :(得分:0)

SET SERVEROUTPUT ON;

    DECLARE
       aswer varchar (10);
       v_corr number(3);
       v_wrong number (3);
       v_unattempt number (3);
       str1  VARCHAR (10);
       str2 VARCHAR (10);
    BEGIN
       answer:= 'AACCABAABD';

       FOR v_stud in c_stud
       LOOP
          v_corr:= 0;
          v_wrong:= 0;
          v_unattempt := 0;

          FOR I IN 1 .. 10
          LOOP
             str2 := SUBSTR (v_stud.ans, i, 1);
             str1 := SUBSTR (answer, i, 1);

             IF (str2 = str1)
             THEN
                v_corr := v_corr + 1;
             ELSIF (str2 = 'E')
             THEN
                v_unattempt := v_unattempt + 1;
             else
                v_wrong:= v_wrong + 1;
             END IF;
          END LOOP;

          UPDATE stud_ans_sheet
          SET 
              corr_ans= v_corr,
              wrong_ans = v_wrong,
             unattempt_ans=v_unattempt , score = v_corr- v_wrong* 0.25,
          WHERE stud_no= v_stud.stud_no;
       END LOOP;

    END;
    /