PL / SQL错误ORA-01403:未找到数据。没有收到预期的结果

时间:2017-11-03 00:29:10

标签: mysql oracle stored-procedures plsql plsqldeveloper

基本上,我在oracle中创建了一个业务报告(查询)来从FREQUENT_FLYER表中提取信息,对于里程余额> 10000但小于20000并且前程万里(MileageExpDate)大于2017年10月1日。

SELECT F.FPASSENGERID, P.First, P.Last, F.FREQFLYERNUM, F.FREQFLYERMILEAGE, 
F.MILEAGEBALANCE, F.MILEAGEEXPDATE
FROM FREQUENT_FLYER F
INNER JOIN PASSENGER P
ON F.FPassengerID = P.PassengerID
WHERE MileageBalance >= 10000 AND F.MILEAGEBALANCE <= 20000
AND MileageExpDate > '01/OCT/2017';

这是该查询的结果。它应该只返回一个记录。 enter image description here

我正在尝试使用存储过程,我决定将该查询转换为存储过程

--First Stored Procedure--
CREATE OR REPLACE PROCEDURE sp_GetMileageBalance 
IS  --Code declaration section--
    --variables to store column values returned from select into
     fPassengerID        VARCHAR2(10);
     pFirst              VARCHAR2(20);
     pLast               VARCHAR2(20);
     fFreqflyernum       NUMBER (10);
     fFreqflyerMileage   NUMBER (7);
     fMileagebalance     NUMBER (7);
     fMileageExpDate     DATE;
     MileageExpDate      DATE;
     MileageStart        NUMBER (7);
     MileageEnd          NUMBER (7);
     MileageBalance      NUMBER (7);

BEGIN --Code execution section
              --executing select into Query assign to variable
              MileageExpDate := '01/OCT/2017';
              MileageStart := 10000;
              MileageEnd :=  20000;
SELECT F.FPASSENGERID, P.First, P.Last, F.FREQFLYERNUM, F.FREQFLYERMILEAGE,  
F.MILEAGEBALANCE, F.MILEAGEEXPDATE
INTO  fPassengerID,  
pFirst,pLast,fFreqflyernum,fFreqflyerMileage,fMileagebalance,fMileageExpDate
FROM FREQUENT_FLYER F
INNER JOIN PASSENGER P
ON F.FPassengerID = P.PassengerID
WHERE MileageBalance >= MileageStart AND F.MILEAGEBALANCE <= MileageEnd
AND MileageExpDate > MileageExpDate;

--Displaying the results
DBMS_OUTPUT.PUT_LINE ('CUSTOMER INFORMATION: ');
DBMS_OUTPUT.PUT_LINE ('The Frequent Flyer PassengerID is:  ' ||fPassengerID);
DBMS_OUTPUT.PUT_LINE ('First Name of passenger is:  ' ||pFirst);
DBMS_OUTPUT.PUT_LINE ('Last Name of passenger is:  ' ||pLast);
DBMS_OUTPUT.PUT_LINE ('Frequent Flyer number of passenger is: ' ||fFreqflyernum);
DBMS_OUTPUT.PUT_LINE ('Frequent Flyer Mileage of Passenger is:  ' ||fFreqflyerMileage);
DBMS_OUTPUT.PUT_LINE ('Frequent Flyer Balance of passenger is:  ' ||MileageBalance );
DBMS_OUTPUT.PUT_LINE ('Mileage expiration date of passenger is:  ' ||MileageExpDate);

END sp_GetMileageBalance;

我期待商店程序根据该记录返回信息。 相反,这就是我得到的。

Procedure SP_GETMILEAGEBALANCE compiled


Error starting at line : 57 in command -
BEGIN sp_GetMileageBalance; END;
Error report -
ORA-01403: no data found
ORA-06512: at "SYSTEM.SP_GETMILEAGEBALANCE", line 29
ORA-06512: at line 1
01403. 00000 -  "no data found"
*Cause:    No data was found from the objects.
*Action:   There was no data from the objects which may be due to end of fetch

我不知道为什么我得到这个结果,因为我应该获得与查询相同的信息。

3 个答案:

答案 0 :(得分:0)

这可能是问题所在:

drop table test_table;
create table test_table ( charcol varchar2(10), numcol integer);
insert into test_table select ' 15000',15000 from dual;

select * from test_table where charcol>'10000'; --no record
select * from test_table where charcol>10000; --1 record  

答案 1 :(得分:0)

为了澄清,MileageStart是在存储过程中创建的变量。它根本不显示在SQL查询中(向上滚动以查看自己)。另外,在我创建的SQL查询中,可以说在这种情况下指定的值被称为字符。

 WHERE MileageBalance >= '10000'

出于某种原因,即使我有#34;字符&#34;在引用中,oracle仍然会给我相同的结果。

 SELECT F.FPASSENGERID, P.First, P.Last, F.FREQFLYERNUM, F.FREQFLYERMILEAGE, 
 F.MILEAGEBALANCE, F.MILEAGEEXPDATE
 FROM FREQUENT_FLYER F
 INNER JOIN PASSENGER P
 ON F.FPassengerID = P.PassengerID
 WHERE F.MileageBalance >= '10000' AND F.MILEAGEBALANCE <= 20000
 AND MileageExpDate > '01/OCT/2017';

结果:   First Query

相同的查询,但删除了字符引号

  SELECT F.FPASSENGERID, P.First, P.Last, F.FREQFLYERNUM, 
  F.FREQFLYERMILEAGE, F.MILEAGEBALANCE, F.MILEAGEEXPDATE
  FROM FREQUENT_FLYER F
  INNER JOIN PASSENGER P
  ON F.FPassengerID = P.PassengerID
  WHERE F.MileageBalance >= 10000 AND F.MILEAGEBALANCE <= 20000
  AND MileageExpDate > '01/OCT/2017';

结果:Second Query

现在,回到商店程序,我们需要了解一件事。声明/创建这些变量的原因:

 fPassengerID        VARCHAR2(10);
 pFirst              VARCHAR2(20);
 pLast               VARCHAR2(20);
 fFreqflyernum       NUMBER (10);
 fFreqflyerMileage   NUMBER (7);
 fMileagebalance     NUMBER (7);
 fMileageExpDate     DATE;
 MileageExpDate      DATE;
 MileageStart        NUMBER (7);
 MileageEnd          NUMBER (7);
 MileageBalance      NUMBER (7);

是因为有占位符存储从数据库中创建的表中提取的任何值(Captain Obvious)。

这是将声明的变量与...进行比较的内容。

SELECT F.FPASSENGERID, P.First, P.Last, F.FREQFLYERNUM, F.FREQFLYERMILEAGE,  
F.MILEAGEBALANCE, F.MILEAGEEXPDATE
INTO  fPassengerID,  
pFirst,pLast,fFreqflyernum,fFreqflyerMileage,fMileagebalance,fMileageExpDate

创建了这些变量:

              MileageExpDate := '01/OCT/2017';
              MileageStart := 10000;
              MileageEnd :=  20000;

无法使用,因为这些变量(虽然已声明)未被创建的任何表中的属性引用。前程万里(MileageStart)&amp; MileageEnd不与任何东西进行比较。像这样离开查询,几乎解决了这个问题。

--First Stored Procedure--
CREATE OR REPLACE PROCEDURE sp_GetMileageBalance 
 IS  --Code declaration section--
    --variables to store column values returned from select into
     fPassengerID        VARCHAR2(10);
     pFirst              VARCHAR2(20);
     pLast               VARCHAR2(20);
     fFreqflyernum       NUMBER (10);
     fFreqflyerMileage   NUMBER (7);
     fMileagebalance     NUMBER (7);
     fMileageExpDate     DATE;
     MileageExpDate      DATE;
     MileageStart        NUMBER (7);
     MileageEnd          NUMBER (7);
     MileageBalance      NUMBER (7);

        BEGIN --Code execution section
          --executing select into Query assign to variable
          --MileageExpDate := '01/OCT/2017';--
          --MileageStart := 10000;--
          --MileageEnd :=  20000;--
         SELECT F.FPASSENGERID, P.First, P.Last, F.FREQFLYERNUM,  
         F.FREQFLYERMILEAGE, F.MILEAGEBALANCE, F.MILEAGEEXPDATE
         INTO  fPassengerID,   
 pFirst,pLast,fFreqflyernum,fFreqflyerMileage,fMileagebalance,fMileageExpDate
FROM FREQUENT_FLYER F
INNER JOIN PASSENGER P
ON F.FPassengerID = P.PassengerID
WHERE F.MileageBalance >= 10000 AND F.MILEAGEBALANCE <= 20000
AND MileageExpDate > '01/OCT/2017';

--Displaying the results
DBMS_OUTPUT.PUT_LINE ('CUSTOMER INFORMATION: ');
DBMS_OUTPUT.PUT_LINE ('The Frequent Flyer PassengerID is:  ' ||fPassengerID);
DBMS_OUTPUT.PUT_LINE ('First Name of passenger is:  ' ||pFirst);
DBMS_OUTPUT.PUT_LINE ('Last Name of passenger is:  ' ||pLast);
DBMS_OUTPUT.PUT_LINE ('Frequent Flyer number of passenger is: ' ||fFreqflyernum);
DBMS_OUTPUT.PUT_LINE ('Frequent Flyer Mileage of Passenger is:  ' ||fFreqflyerMileage);
DBMS_OUTPUT.PUT_LINE ('Frequent Flyer Balance of passenger is:  ' ||fMileageBalance );
DBMS_OUTPUT.PUT_LINE ('Mileage expiration date of passenger is:  ' ||fMileageExpDate);

END sp_GetMileageBalance;

结果:

CUSTOMER INFORMATION: 
The Frequent Flyer PassengerID is:  KL87DF34DS
First Name of passenger is:  Michelle
Last Name of passenger is:  Mullington
Frequent Flyer number of passenger is: 9374392018
Frequent Flyer Mileage of Passenger is:  400
Frequent Flyer Balance of passenger is:  15000
Mileage expiration date of passenger is:  19-DEC-20


PL/SQL procedure successfully completed.

答案 2 :(得分:0)

从你的proc:
AND MileageExpDate&gt; MileageExpDate;

你知道吗?

更改变量名称,使其与列名称或变量名称前缀与过程名称区分开来。如下所示:

前程万里(MileageExpDate)&gt; sp_GetMileageBalance.MileageExpDate

此处有详细解释:Link