0

Je veux joindre une table dire EMPLOYEE avec un autre type d'oracle personnalisé MATCHING_CRITERIA_LIST. MATCHING_CRITERIA_LIST est une table d'un CRITERIA de type oracle personnalisé. Tous DDL comme suit:joindre la table de base de données oracle avec la table de type personnalisé

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 
} 

Ce que je suis en train d'essayer d'atteindre est,

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); 
     } 
    } 
} 

Je veux que cette même logique d'être en SP. Je suis en train de faire ce qui suit qui fonctionne bien.

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; 

Je veux enlever la boucle sur IN_CRITERIA_LIST, car il impacte la performance, et faire quelque chose comme ci-dessous:

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; 

Quelqu'un peut-il guider comment je peux joindre ma table personnalisée de UDT et table d'oracle?

+0

Je ne peux pas créer une table temporaire et mettez tous matching_criteria_list en elle, comme nous le appelez le SP à partir d'une application multithread. –

+0

Oracle n'a pas de type de données 'DATETIME' - il a' DATE' (années en secondes) ou 'TIMESTAMP' (années en secondes fractionnelles plus fuseau horaire optionnel). – MT0

Répondre

0

Cela a fonctionné pour moi. Merci.

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

Vous n'avez pas besoin d'un objet IDTYPE ou toutes les boucles PL/SQL (ou même des jointures):

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

Comment CRITERIA (dob, salaire) ci-dessus sera mappé aux colonnes respectives de la table EMPLOYEE? Cela implique-t-il d'écrire une jointure comme dans ma réponse ci-dessus? –

+0

@shrutisingh Il n'y a pas de jointure, juste un filtre contre la collection transmise en tant que paramètre de liaison. – MT0

+0

@shrutisingh Vous pouvez consulter le plan d'explication de 'SELECT * FROM EMPLOYEE WHERE CRITERIA (dob, salary) MEMBRE DE MATCHING_CRITERIA_LIST (CRITERIA (DATE '1970-01-01', 20000))' et voir qu'il n'y a pas de jointure. – MT0