0

我想加入一個表,說與EMPLOYEE與另一個自定義oracle類型MATCHING_CRITERIA_LIST。 MATCHING_CRITERIA_LIST是自定義oracle類型CRITERIA的表。所有DDL如下:加入oracle數據庫表與自定義類型表

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循環,因爲它是影響性能,並做一些象下面這樣:

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表?

+0

我不能創建一個臨時表,並把所有matching_criteria_list進去,因爲我們會從多線程應用程序調用SP。 –

+0

Oracle沒有'DATETIME'數據類型 - 它具有'DATE'(年至秒)或'TIMESTAMP'(年至小數秒加可選時區)。 – MT0

回答

0

這對我有用。謝謝。

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; 
0

你並不需要一個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; 
/
+0

上面的CRITERIA(dob,salary)將如何映射到EMPLOYEE表的相應列?這是否意味着按照我上面的回答寫一個連接? –

+0

@shrutisingh沒有聯接,只是針對作爲綁定參數傳入的集合的過濾器。 – MT0

+0

@shrutisingh你可以看看SELECT * FROM EMPLOYEE WHERE CRITERIA(dob,salary)會員的MATCHING_CRITERIA_LIST(CRITERIA(DATE'1970-01-01',20000))'的解釋計劃,看看沒有加入。 – MT0