ORACLE自定义函数返回记录集(表类型)的写法

ORACLE自定义函数返回记录集(表类型)的写法:

create type concept.row_type2 as object(CODEDTERMID     NUMBER(10), CODEID NUMBER(10), CODE VARCHAR2(50 CHAR), DISPLAYNAME NVARCHAR2(50),
   SHORTNAME NVARCHAR2(50), SPELLCODE VARCHAR2(50 CHAR), WBCODE VARCHAR2(50 CHAR), MNEMONICCODE VARCHAR2(50 CHAR),
   NOTE NVARCHAR2(100), PARENTCODEID  NUMBER(10), VALUEKIND NUMBER(5), ISDELETED NUMBER(1), FULLCODE VARCHAR2(50 CHAR));  
/
create type concept.table_type2 as table of row_type2;    
/
create or replace function concept.getCodedTermValues(codedTermIds varchar2) return concept.table_type2 
pipelined as  v row_type2;  
begin 
  for r in 
  (
    select CODEDTERMID, CODEID, CODE, DISPLAYNAME, SHORTNAME, SPELLCODE, WBCODE, MNEMONICCODE, NOTE, PARENTCODEID, VALUEKIND, ISDELETED, FULLCODE 
    from concept.CODEDTERMVALUE a, table(concept.fnIDInString(codedTermIds, ',')) b 
    where a.CODEDTERMID = b.COLUMN_VALUE
  ) loop  
  v := row_type2(r.CODEDTERMID, r.CODEID, r.CODE, r.DISPLAYNAME, r.SHORTNAME, r.SPELLCODE, r.WBCODE, r.MNEMONICCODE, r.NOTE, r.PARENTCODEID, r.VALUEKIND, r.ISDELETED, r.FULLCODE); 
  pipe row (v); 
  end loop; 
  return; 
end;  
/
select * from table(concept.getCodedTermValues('4,38,99,10883,10844,10918,11081,11155,11346'));

create or replace FUNCTION         concept.fnIDInString(p_string IN VARCHAR2, p_delimiter IN VARCHAR2)
    RETURN  type_str_split  
    PIPELINED
AS
    v_length   NUMBER := LENGTH(p_string);
    v_start    NUMBER := 1;
    v_index    NUMBER;
BEGIN
    WHILE(v_start <= v_length)
    LOOP
        v_index := INSTR(p_string, p_delimiter, v_start);

        IF v_index = 0
        THEN
            PIPE ROW(SUBSTR(p_string, v_start));
            v_start := v_length + 1;
        ELSE
            PIPE ROW(SUBSTR(p_string, v_start, v_index - v_start));
            v_start := v_index + 1;
        END IF;
    END LOOP;

    RETURN;
END ;

WITH子句的使用:

With查询语句不是以select开始的,而是以“WITH”关键字开头
    可认为在真正进行查询之前预先构造了一个临时表TT,之后便可多次使用它做进一步的分析和处理

WITH Clause方法的优点
     增加了SQL的易读性,如果构造了多个子查询,结构会更清晰;更重要的是:“一次分析,多次使用”,这也是为什么会提供性能的地方,达到了“少读”的目标。

     第一种使用子查询的方法表被扫描了两次,而使用WITH Clause方法,表仅被扫描一次。这样可以大大的提高数据分析和查询的效率。

     另外,观察WITH Clause方法执行计划,其中“CV”便是在运行过程中构造的中间统计结果临时表

WITH cv AS ( select CODEDTERMID, CODEID, CODE, DISPLAYNAME, SHORTNAME, SPELLCODE, WBCODE, MNEMONICCODE, NOTE, PARENTCODEID, VALUEKIND, ISDELETED, FULLCODE 
    from concept.CODEDTERMVALUE WHERE CODEDTERMID in (4,38,99,10883,10844,10918,11081,11155,11346) )
select e.EncounterId,e.PersonId,e.IsDeleted,e.MaritalStatusCodeId,e.MedicareTreatmentId,e.IsTransferred,e.SourceKindCodeId,e.NoticeStatusCodeId,e.AuditKindCodeId,
    v1.Code as EncounterKindCode,e.EncounterKindCodeId as EncounterKindCodeSystem,v1.DisplayName as EncounterKindCodeName,
    e.SeqNoText,e.IPTimes,
    e.SickBedId,sb.No as SickBedNo,e.SickBedOrganizationId,
    e.DisplayName,e.BirthTime,
    v2.Code as GenderCode,e.GenderCodeId as GenderCodeSystem,v2.DisplayName as GenderCodeName,
    e.PatientTypeId,e.PaymentRatio,
    e.MedicareType,v9.Code as MedicareTypeCode,e.MedicareType as MedicareTypeCodeSystem,v3.DisplayName as MedicareTypeCodeName,
    v3.Code as DischargeDispositionCode,e.DischargeDispositionCodeId as DischargeDispositionCodeSystem,v3.DisplayName as DischargeDispositionCodeName,
    e.AdmitDateOn,
    e.AdmitDepartmentId,ao.Code as AdmitOrganizationCode,
    e.AdmitSickBedOrganizationId,
    e.AdmitterId,
    v4.Code as AdmitStateCode,e.AdminStateCodeId as AdmitStateCodeSystem,v4.DisplayName as AdmitStateCodeName,
    e.DischargeOn,
    e.DischargerId,
    e.ResponsibleDepartmentId,ro.Code as ResponsibleOrganizationCode,
    v5.Code as IPStatusCode,e.StatusCodeId as IPStatusCodeSystem,v5.DisplayName as IPStatusCodeName,
    v6.Code as DifficultyLevelCode,e.DifficultyLevelCodeId as DifficultyLevelCodeSystem,v6.DisplayName as DifficultyLevelCodeName,
    e.ContactPersonName,
    v7.Code as ContactRelationShipCode,e.ContactPersonRelationCodeId as ContactRelationShipCodeSystem,v7.DisplayName as ContactRelationShipCodeName,
    e.ContactPersonAddress,e.ContactPersonPhone,
    e.BabyFlag,
    eaa.AttributeValue as AdmitWeight,eab.AttributeValue as BirthWeight,
    v7.Code as AdmitWayCode,e.AdmitWayCodeId as AdmitWayCodeSystem,v7.DisplayName as AdmitWayCodeName,
    e.MedicineLimitAmount,e.SickBedLimitAmount,e.ExamineLimitAmount,e.CureLimitAmount,
    e.SecurityLevel,
    ep1.EntityId as DirectorII,e1.Name as Director,
    ep2.EntityId as ChiefDoctorII,e2.Name as ChiefDoctor,
    ep3.EntityId as AttendingDoctorII,e3.Name as AttendingDoctor,
    ep4.EntityId as IPDoctorII,e4.Name as IPDoctor,
    e.RowVersion,
    ei.Extension as InPatientII,pi.Extension as PatientII  
    from prpa.Encounter e
    left join prpa.EncounterII ei on e.EncounterId=ei.EncounterId and ei.RootId=364
    left join entity.PersonII pi on e.PersonId=pi.PersonId and pi.RootId=363
    left join cv v1 on e.EncounterKindCodeId=v1.CodeId and v1.CODEDTERMID=38
    left join concept.SickBed sb on e.SickBedId=sb.SickBedId
    left join cv v2 on e.GenderCodeId=v2.CodeId and v2.CODEDTERMID=4
    left join cv v3 on e.DischargeDispositionCodeId=v3.CodeId and v3.CODEDTERMID=11346
    left join entity.Organization ao on e.AdmitDepartmentId=ao.OrganizationId
    left join cv v4 on e.AdminStateCodeId=v4.CodeId and v4.CODEDTERMID=10883
    left join entity.Organization ro on e.ResponsibleDepartmentId=ro.OrganizationId
    left join cv v5 on e.StatusCodeId=v5.CodeId and v5.CODEDTERMID=10844
    left join cv v6 on e.DifficultyLevelCodeId=v6.CodeId and v6.CODEDTERMID=10918
    left join cv v7 on e.ContactPersonRelationCodeId=v7.CodeId and v7.CODEDTERMID=99
    left join cv v8 on e.AdmitWayCodeId=v8.CodeId and v8.CODEDTERMID=11081
    left join cv v9 on e.MedicareType=v9.CodeId and v9.CODEDTERMID=11155
    left join prpa.EncounterParticipation ep1 on ep1.IsLast=1 and ep1.IsDeleted=0 and ep1.RoleCodeId=33 and ep1.EncounterId=e.EncounterId
    left join role.Employee e1 on e1.EmployeeId=ep1.EntityId
    left join prpa.EncounterParticipation ep2 on ep2.IsLast=1 and ep2.IsDeleted=0 and ep2.RoleCodeId=32 and ep2.EncounterId=e.EncounterId
    left join role.Employee e2 on e2.EmployeeId=ep2.EntityId
    left join prpa.EncounterParticipation ep3 on ep3.IsLast=1 and ep3.IsDeleted=0 and ep3.RoleCodeId=31 and ep3.EncounterId=e.EncounterId
    left join role.Employee e3 on e3.EmployeeId=ep3.EntityId
    left join prpa.EncounterParticipation ep4 on ep4.IsLast=1 and ep4.IsDeleted=0 and ep4.RoleCodeId=30 and ep4.EncounterId=e.EncounterId
    left join role.Employee e4 on e4.EmployeeId=ep4.EntityId
    left join prpa.EncounterAttribute eaa on e.EncounterId=eaa.EncounterId and eaa.Attribute='AdmitWeight'
    left join prpa.EncounterAttribute eab on e.EncounterId=eab.EncounterId and eab.Attribute='BirthWeight'
    where e.IsDeleted=0;
原文地址:https://www.cnblogs.com/chriskwok/p/12858830.html