使用自定义类型的表加入oracle数据库表

时间:2017-09-26 06:36:39

标签: database oracle stored-procedures inner-join user-defined-types

我想加入一个表,说EMPLOYEE与另一个自定义oracle类型MATCHING_CRITERIA_LIST。 MATCHING_CRITERIA_LIST是自定义oracle类型CRITERIA的表。所有DDL如下:

CREATE OR REPLACE
type CRITERIA as object (
DOB DATETIME,
SALARY NUMBER
);

CREATE OR REPLACE TYPE
MATCHING_CRITERIA_LIST IS TABLE OF CRITERIA;

CREATE TABLE EMPLOYEE{
    ID NUMBER PRIMARY KEY NOT NULL,
    NAME VARCHAR(20 BYTE),
    DOB DATETIME,
    SALARY NUMBER
}

我实际想要实现的是,

var allEmployeeList = new List<Employee>();
var filteredList = new List<Employee>();
var matchingCriteria = new List<MatchingCritera>{
    new MatchingCritera(){DOB = <date1>, salary = <sal1>},
    new MatchingCritera(){DOB = <date2>, salary = <sal2>},
    new MatchingCritera(){DOB = <date3>, salary = <sal1>}
}
foreach(var emp in allEmployeeList)
{
    foreach(var criteria in matchingCriteria)
    {
        if(emp.DOB == criteria.DOB && emp.salary = criteria.salary)
        {
            filteredList.Add(emp);
        }
    }
}

我希望在SP中使用相同的逻辑。我目前正在做如下工作正常。

CREATE OR REPLACE
type IDTYPE as object (
id NUMBER
);
CREATE OR REPLACE
type IDTABLETYPE IS TABLE OF IDTYPE;

CREATE OR REPLACE PROCEDURE GET_FILTERED_EMPLOYEE (
   IN_CRITERIA_LIST   IN       MATCHING_CRITERIA_LIST,
   CUR_OUT            OUT      sys_refcursor
)
IS

V_ID_TABLE IDTABLETYPE;
V_TEMP_ID_COLL EMPLOYEE_ID;

BEGIN

   V_ID_TABLE := IDTABLETYPE();
   V_TEMP_ID_COLL := EMPLOYEE_ID();

   IF IN_CRITERIA_LIST.COUNT > 0 THEN
     FOR i IN IN_CRITERIA_LIST.FIRST .. IN_CRITERIA_LIST.LAST
     LOOP
        SELECT EMP.ID BULK COLLECT INTO V_TEMP_ID_COLL FROM EMPLOYEE EMP WHERE
        EMP.DOB = IN_CRITERIA_LIST(i).DOB
        AND EMP.SALARY = IN_CRITERIA_LIST(i).SALARY
        ORDER BY EMP.ID DESC;

        IF (V_TEMP_ID_COLL.COUNT > 0) THEN
         FOR j IN V_TEMP_ID_COLL.FIRST .. V_TEMP_ID_COLL.LAST
          LOOP
            V_ID_TABLE.extend();
            V_ID_TABLE(V_ID_TABLE.count) := IDTYPE(TO_NUMBER(V_TEMP_ID_COLL(j)));
          END LOOP;
        END IF;
     END LOOP;
   END IF;

   OPEN CUR_OUT FOR
   SELECT * FROM EMPLOYEE EMP WHERE EMP.ID IN (SELECT * FROM TABLE(V_ID_TABLE));
END;

我想删除IN_CRITERIA_LIST上的for循环,因为它会影响性能,并执行以下操作:

SELECT * FROM EMPLOYEE EMP
INNER JOIN MATCHING_CRITERIA_LIST MCL ON 
EMP.DOB = MCL.DOB
AND EMP.SALARY = MCL.SALARY
ORDER BY TD.TRANS_DASHBOARD_ID DESC;

有人可以指导我如何加入我的UDT自定义表和oracle表吗?

2 个答案:

答案 0 :(得分:1)

这对我有用。感谢。

SELECT * FROM EMPLOYEE EMP
INNER JOIN TABLE(IN_CRITERIA_LIST) MCL ON 
EMP.DOB = MCL.DOB
AND EMP.SALARY = MCL.SALARY
ORDER BY TD.TRANS_DASHBOARD_ID DESC;

答案 1 :(得分:1)

您不需要IDTYPE个对象或所有PL / SQL循环(甚至连接):

CREATE OR REPLACE PROCEDURE GET_FILTERED_EMPLOYEE (
   IN_CRITERIA_LIST   IN       MATCHING_CRITERIA_LIST,
   CUR_OUT            OUT      sys_refcursor
)
IS
BEGIN
  OPEN CUR_OUT FOR
    SELECT *
    FROM   EMPLOYEE
    WHERE  CRITERIA( dob, salary ) MEMBER OF IN_CRITERIA_LIST;
END;
/