游标返回太多重复项

时间:2015-04-28 00:00:32

标签: php sql database oracle procedure

我的程序似乎有问题。它用于搜索并且它正确地获得搜索但是返回了相同的答案太多次以至于我得到了耗尽内存的致命错误。这是我的代码:

FUNCTION pet_search(PETTYPE in VARCHAR2, BREED in VARCHAR2, COLOR in VARCHAR2, PETSIZE in VARCHAR2, TS in VARCHAR2, ENERGY in VARCHAR2, SPACE in VARCHAR2)
       RETURN SYS_REFCURSOR
       IS 
          pet_search_result SYS_REFCURSOR; 
          type_id NUMBER;
          breed_id NUMBER;
          color_id NUMBER;
          size_id NUMBER;  
          TS_id NUMBER; 
          energy_id NUMBER; 
          space_id NUMBER;

       BEGIN  

       select TP.pet_type_code into type_id
       from dbadmin.petType TP
       where TP.pet_type_name = PETTYPE;

       select B.pet_race_code into breed_id
       from dbadmin.petRace B
       where B.pet_race_name = BREED;

      select PC.pet_color_code into color_id
      from dbadmin.PetColor PC
      where PC.pet_color = COLOR;

      select PS.pet_size_code into size_id
      from dbadmin.PetSize PS
      where PS.pet_size = PETSIZE;  

      select LS.pet_learn_code into TS_id
      from dbadmin.petlearningskill LS
      where LS.pet_learn_skill = TS;

      select EN.pet_energy_code into energy_id
       from dbadmin.petEnergy EN
       where EN.pet_energy_level = ENERGY;

       select SP.pet_space_code into space_id
       from dbadmin.petSpace SP
       where SP.pet_space = SPACE; 

    OPEN pet_search_result FOR select pet_type_name, pet_race_name, pet_cond_name, pet_energy_level, pet_learn_skill, vet_name, person_name, petlocation, petnotes, petabandondescription, pet_space, pet_treatment, pet_color, pet_sickness_name, pet_med_name
    from pet, pettype, petrace, petCondition, petSize,petEnergy, petlearningskill, veterinary, person, petSpace, pettreatments, petcolor, petsickness, petmedicine
    WHERE pettype.pet_type_code = type_id
    AND petrace.pet_race_code = breed_id  
    AND pet.pet_color_code = color_id
    AND pet.pet_size_code = size_id  
    AND pet.pet_learn_code = TS_id 
    AND pet.pet_energy_code = energy_id 
    AND pet.petspace_id = space_id;
        RETURN pet_search_result; 

      EXCEPTION 
        WHEN NO_DATA_FOUND THEN 
          RETURN null;
      END; 

END pet_search_package; 
你能看出我的错误吗? 任何建议将不胜感激

2 个答案:

答案 0 :(得分:0)

问题似乎出现在select查询中,如果你的where子句确实满足所有条件,那么由于 join ,行将被复制。 请参阅下面的示例,说明问题以及解决方法。

select pet_type_name, pet_race_name, pet_cond_name, pet_energy_level, pet_learn_skill, vet_name, person_name, petlocation, petnotes, petabandondescription, pet_space, pet_treatment, pet_color, pet_sickness_name, pet_med_name
    from pet, pettype, petrace, petCondition, petSize,petEnergy, petlearningskill, veterinary, person, petSpace, pettreatments, petcolor, petsickness, petmedicine
    WHERE pettype.pet_type_code = type_id
    AND petrace.pet_race_code = breed_id  
    AND pet.pet_color_code = color_id
    AND pet.pet_size_code = size_id  
    AND pet.pet_learn_code = TS_id 
    AND pet.pet_energy_code = energy_id 
    AND pet.petspace_id = space_id;

例如,这里有两个表emp和dept,

        SQL> select * from emp;

      EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
 ---------- ---------- --------- ---------- --------- ---------- ---------- ----------
       7369 SMITH      CLERK           7902 17-DEC-80        800                    20
       7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
       7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
       7566 JONES      MANAGER         7839 02-APR-81       2975                    20
       7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
       7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
       7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
       7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
       7839 KING       PRESIDENT            17-NOV-81       5000                    10
       7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30
       7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20
       7900 JAMES      CLERK           7698 03-DEC-81        950                    30
       7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
       7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

 14 rows selected.

SQL> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

如果满足where子句中的所有条件,则此查询将仅返回1行。

SQL> select a.empno,b.deptno,a.ename from emp a,dept b where a.empno=7369 and b.deptno=20;

     EMPNO     DEPTNO ENAME
---------- ---------- ----------
      7369         20 SMITH

如果条件where子句不完全匹配,或者差异数量较少,它将返回重复项。

SQL> select a.empno,b.deptno,a.ename from emp a,dept b where a.empno=7369 ;

      EMPNO     DEPTNO ENAME
  --------- ---------- ----------
       7369         10 SMITH
       7369         20 SMITH
       7369         30 SMITH
       7369         40 SMITH

如果你在这些表之间有引用,那么建议在where子句中使用它然后比较

答案 1 :(得分:0)

在主查询的FROM子句中包含十几个引用数据表。但是,您不会限制它们,以便它们返回所有行。此外,您不能将他们加入数据表PET。这会产生交叉连接或笛卡尔积,它为这些表中的每个记录组合生成一行

以下是您的查询重写,以便明确发生了什么,以及它是否正常运行:

OPEN pet_search_result FOR 
    select pet_type_name
            , pet_race_name
            , pet_cond_name
            , pet_energy_level
            , pet_learn_skill
            , vet_name
            , person_name
            , petlocation
            , petnotes
            , petabandondescription
            , pet_space
            , pet_treatment
            , pet_color
            , pet_sickness_name
            , pet_med_name
    from pet
        join pettype TP
            on pet.pet_type_code = TP.pet_type_code
        join petrace B
            on pet.pet_race_code = B.pet_race_code
        join petSize PS
            on pet.pet_size_code = PS.pet_size_code
        join petEnergy EN
            on pet.pet_energy_code = EN.pet_energy_code
        join petcolor pc
            on pet.pet_color_code = PC.pet_color_code
        join petlearningskill LS
            on pet.pet_learn_code = LS.pet_learn_code 
        join petSpace SP
            on pet.petspace_id = SP.pet_space_code
    where TP.pet_type_name = PETTYPE
    and   B.pet_race_name = BREED
    and   PS.pet_size = PETSIZE
    and   PC.pet_color = COLOR
    and   EN.pet_energy_level = ENERGY
    and   LS.pet_learn_skill = TS
    and   SP.pet_space = SPACE;

以这种方式编写意味着您可以在程序开始时丢弃所有这些小视图。

我省略了下表。您还没有提供限制它们的任何条件,因此它们不会影响结果集。

  • pettreatments
  • petCondition
  • petsickness
  • petmedicine
  • veterinary
  • person