尝试在游标创建中使用where语句(PL / SQL)

时间:2015-04-19 02:09:35

标签: sql oracle plsql oracle11g

我正在尝试创建一个接受来自提示输入的块,并使用该输入来过滤游标的结果集。请记住,我是一个新手,所以我可能会犯一个常规的错误,谢谢你的帮助。我目前的代码如下。

Set serveroutput on

DECLARE
  ACCEPT a PROMPT  “Please Enter a Date,  eg. Format -  01 or 30"

  datev char
  datev := &a;

  CURSOR cur_day_cursor IS
    SELECT Arrival_Date Adate
      FROM FLIGHT
      WHERE TO_CHAR(Arrival_Date, ‘DD’) = datev;

  cur_day_cursor_var cur_day_cursor%ROWTYPE;
BEGIN
  OPEN Cur_day_cursor;

  LOOP
    Fetch Cur_day_cursor
      INTO cur_day_cursor_var;
    EXIT WHEN cur_day_cursor%NOTFOUND;

    DBMS_OUTPUT.PUT_LINE (cur_day_cursor_var.Adate);
  END LOOP;

  IF cur_day_cursor%ISOPEN THEN
    CLOSE cur_day_cursor;
  END IF;
END;

where语句导致我的错误,所以我想我可能不得不让光标收集所有数据然后在显示时过滤它,但我不确定我是否能做到这一点。

我在第9行收到错误的错误: - ORA-06550:第9行第1列: PLS-00103:遇到以下其中一项时遇到符号“WHERE”: 开始函数编译指示程序子类型  当前游标删除 先前存在

3 个答案:

答案 0 :(得分:0)

我不确切知道Oracle在WHERE报告错误的原因。有时解析器会因语法错误而感到困惑,并没有指出真正的问题。在游标定义之前,您有几个语法错误。

ACCEPT是SQLPlus命令,而不是PL / SQL语句。将ACCEPT行移到DECLARE上方。

此外,您的变量声明和初始化不正确。转让应该是申报行的一部分;您需要为CHAR数据类型提供长度;并且替换值应该在引号中以作为字符串处理。您的行的有效版本将是:

datev  char(2) := '&a';

答案 1 :(得分:0)

问题似乎是‘DD’周围的单引号不是单引号。看起来代码是在编辑器中创建的,它将撇号变为那些特殊的“看起来像单引号但不是真正的”字符。用以下内容替换WHERE子句的原始版本:

WHERE TO_CHAR(Arrival_Date, 'DD') = datev;

我怀疑你会没事的。

让自己成为一名优秀的代码编辑器。 : - )

分享并享受。

答案 2 :(得分:0)

我运行了与上面相同的查询,并且结果非常好。 您在查询中更正了语法和逻辑错误。语法错误是 -

datev char
datev := &a;

您无法在PL / SQL中进行此类初始化。你可能需要在一行中完成它 - 如下所示 -

datev char := &a;

逻辑错误是 -

  1. 当您知道返回的值为NUMBER时,为什么使用CHAR变量来存储数据。
  2. 您期望1-31的数字;那你为什么选择char的默认大小为1.如果你提供一个2位数字
  3. ,它将会失败
  4. 即使您将CHAR的大小增加到CHAR(2),当用户输入1或01这样的数字时,您也不会得到结果,因为为了进行字符比较,' 1' !=' 1'(由于char(2),在末尾标记额外的空格);还有' 1' !=' 01'。 上面唯一的解决方案是使用NUMBER数据类型。
  5. 现在,我发布的查询类似于您的查询,并更改了列名和表名。请替换为您的所需名称并尝试 - (注意不要执行ACCEPT ....)PL / SQL块。它应该先在SQL提示符下完成,然后再运行另一个DECLARE部分。

    --ACCEPT a NUMBER PROMPT  'Please Enter a Date,  eg. Format -  01 or 30 :'
    --Run the above line first in SQL Prompt and then execute the rest as whole
    DECLARE
      datev NUMBER(2) := &a;
      CURSOR cur_day_cursor IS
        SELECT Ename, HireDate Adate
          FROM Emp
          WHERE TO_CHAR(HireDate, 'D') = datev;
      cur_day_cursor_var cur_day_cursor%ROWTYPE;
    BEGIN
      OPEN Cur_day_cursor;
      LOOP
        Fetch Cur_day_cursor
          INTO cur_day_cursor_var;
        EXIT WHEN cur_day_cursor%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE (cur_day_cursor_var.Adate);
      END LOOP;
      IF cur_day_cursor%ISOPEN THEN
        CLOSE cur_day_cursor;
      END IF;
    END;
    /