【问题标题】:SQL Function and Anonymous blockSQL 函数和匿名块
【发布时间】:2013-11-17 22:20:47
【问题描述】:

我正在上一门关于数据库的课程。我对它很陌生,如果这是一个明显的错误,请原谅,但我已经解决这个问题几个小时了,不知道还能做什么。

该代码假设为此创建一个函数
A.) 输出由参数给出的一年的平均 netwin (由公式 (SeasonW-Seasonl) + (PlayoffW - PlayoffL)
B.) 输出净胜率高于平均水平的所有教练
C.) 返回符合此条件的教练数量。
D.)有一个匿名块调用此函数,并根据函数的返回输出两条不同的消息。

现在我已经成功完成了 A、C 和 D 部分。但是由于某种原因,当我插入 B 部分时,我的函数不会被创建。

create or replace function GOOD_COACHES(season IN INT)
return INT
IS
netwin INT;
CNT INT;
BEGIN
       --Calculated netwin
       select AVG((SEASON_WIN-SEASON_LOSS) + (PLAYOFF_WIN-PLAYOFF_LOSS)) into  netwin from COACHESSEASON where YEAR = season; 

       --Prints out A
       dbms_output.put_line('Average Netwin is: ' || netwin);

       --This Line messes up the function, I don't know why
       select T.FIRSTNAME, T.LASTNAME from COACHESSEASON T where ((T.SEASON_WIN-T.SEASON_LOSS) + (T.PLAYOFF_WIN-T.PLAYOFF_LOSS))>netwin and YEAR = season;

       --Calculates the number of teams that satisfy average
        select count(T.FIRSTNAME) into CNT from COACHESSEASON T where ((T.SEASON_WIN-T.SEASON_LOSS) + (T.PLAYOFF_WIN-T.PLAYOFF_LOSS))>netwin and YEAR = season;

return CNT;
END;
--End of the Function
--Start of the Anonymous Block
 DECLARE
      x int := GOOD_COACHES(1998);
 BEGIN
      if x = 0 then dbms_output.put_line('We didn''t find any good_coaches!');
      else dbms_output.put_line('The No. of good coaches is ' || x);
      end if;
END;
/

函数中的第三行把它弄乱了,不允许调用它。如果我将其注释掉,它会正常工作。 当我把它从函数中取出并变成一个常规的 SQL 语句时,它就可以工作了。

select T.FIRSTNAME, T.LASTNAME from COACHESSEASON T where ((T.SEASON_WIN-T.SEASON_LOSS) + (T.PLAYOFF_WIN-T.PLAYOFF_LOSS))>0 and YEAR = /*RandYear*/;

如果有人理解为什么无法使用该行创建函数,我将不胜感激。我也不知道如何在函数中打印出所选行的结果。

【问题讨论】:

  • 函数本身并不是SQL的一部分,而是特定的数据库管理系统(DBMS)带来的东西,而且各种系统往往以不同的方式来做,所以你需要告诉我们您正在使用什么 DBMS。
  • sqlplus 不是 DBMS,而是 Oracle 的程序。根据语法,它是 Oracle。如果你想让函数打印一些东西,你需要使用 dbms_output。当你选择FIRSTNAME和LASTNAME时,选择它们到variables和put_line类似于netwin string

标签: sql oracle sql-function


【解决方案1】:

您没有选择 T.FIRSTNAMEs 和 T.LASTNAMEs 到任何内容中,因此该语句对于包含在 PL/SQL 块中无效。

可能有多个“好教练”,因此您不能将值放入单个变量中,而必须使用游标或集合。

使用集合,如果您创建一个表类型来将名字和姓氏收集到:

CREATE TYPE VARCHAR2s_Table AS TABLE OF VARCHAR2(30);
/

然后你可以用它来收集名字和姓氏(作为奖励,收集大小会告诉你有多少优秀的教练,你可以跳过最后一个查询):

create or replace function GOOD_COACHES(season IN INT)
return INT
IS
netwin INT;
CNT INT;
firstnames VARCHAR2s_Table;
lastnames  VARCHAR2s_Table;
BEGIN
  --Calculated netwin
  select AVG((SEASON_WIN-SEASON_LOSS) + (PLAYOFF_WIN-PLAYOFF_LOSS))
  into   netwin
  from   COACHESSEASON
  where  YEAR = season; 

  --Prints out A
  dbms_output.put_line('Average Netwin is: ' || netwin);

  --This Line messes up the function, I don't know why
  select T.FIRSTNAME, T.LASTNAME
  BULK COLLECT INTO firstnames, lastnames
  from   COACHESSEASON T
  where  ((T.SEASON_WIN-T.SEASON_LOSS) + (T.PLAYOFF_WIN-T.PLAYOFF_LOSS))>netwin
  and    YEAR = season;

  FOR i IN 1 .. firstnames.COUNT LOOP
    DBMS_OUTPUT.put_line( firstnames(i) || ' ' || lastnames(i) );
  END LOOP;

  return firstnames.COUNT;
END;
/

SQLFIDDLE

【讨论】:

    猜你喜欢
    • 2014-09-30
    • 2022-01-06
    • 2013-08-15
    • 1970-01-01
    • 2017-09-02
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多