如何加入oracle表值函数?

时间:2016-05-13 13:33:23

标签: sql oracle function join

是否可以加入Oracle表值函数? 我想要查询和内部联接功能。如何加入?

查询Oracle

   select a.*
   from PMOP_TEST l
   inner join table(packages.FNC_LST_OUR('test','test','test')) a on l.com_code=a.com_code and a.pn_code=l.pn_code

语句查询

com_code | pn_code | OUR
AAA      | AW      |0
AAA      | AQ      |5
AAB      | AQ      |10
AAA      | CV      |2

语句错误查询:ORA-22905

示例数据函数

com_code | pn_code | DESCRIPT
AAA      | AW      | test1
AAA      | AQ      | test2
AAB      | AQ      | test2
AAA      | CV      | test3
AAB      | FG      | test1

Sampla数据声明表PMOP_TEST

com_code | pn_code | DESCRIPT | OUR
AAA      | AW      | test1    | 0
AAA      | AQ      | test2    | 5
AAA      | CV      | test3    | 2

我想要加入函数值结果:

#!/bin/bash
#$ -S /bin/bash

spp_run=/path/tools/phantompeakqualtools/run_spp.R
bam_loc=/path/ChIP-Seq/output

samples="S_12_O_319_K27me3
S_12_O_319_K4me1
S_12_O_319_K4me3"

for s in $samples; do
    echo "Running SPP on $s ..."
    echo $bam_loc/$s/${s}_S*.sorted.bam
    inbam=$bam_loc/$s/${s}_S*.sorted.bam
    echo $inbam
    infile=`echo $inbam`
    Rscript $spp_run -c=$infile -savp -out=$bam_loc/$s/${s}".run_spp.out"
done
echo "done"

请帮帮我。谢谢提前;)

3 个答案:

答案 0 :(得分:1)

您的动态查询可以像这样用SQL表示(将输入指定为绑定变量):

select s.com_code, s.pn_code, count(*) as our   
from   pmtest s 
       inner join PMOP_TEST l
       on (s.com_code=l.com_code and s.pn_code=l.pn_code)
where  s.com_code = :p_code
and    ( :p_pm_from IS NULL OR s.pn_code between :p_pm_from and :p_pm_to )
group by s.com_code,s.pn_code

然后您可以将其加入到您的其他查询中:

select a.*
from   PMOP_TEST l
       inner join (
         select s.com_code,
                s.pn_code,
                count(*) as our   
         from   pmtest s 
                inner join PMOP_TEST l
                on (s.com_code=l.com_code and s.pn_code=l.pn_code)
         where  s.com_code = :p_code
         and    ( :p_pm_from IS NULL OR s.pn_code between :p_pm_from and :p_pm_to )
         group by s.com_code,s.pn_code
       ) a
       on l.com_code=a.com_code and a.pn_code=l.pn_code

您已经使用SQL完成了所有操作,并且不需要使用集合或流水线查询。

答案 1 :(得分:0)

样品:

CREATE TYPE FNC_LST_OUR_TYPE AS OBJECT
(
   com_code VARCHAR2 (20),
   pn_code VARCHAR2 (20),
   our NUMBER
);
/
CREATE TYPE FNC_LST_OUR_TYPE_T AS TABLE OF FNC_LST_OUR_TYPE;
/
CREATE OR REPLACE PACKAGE pkg
AS
   FUNCTION FNC_LST_OUR (p_code VARCHAR2, p_pm_from VARCHAR2, p_pm_to VARCHAR2)
      RETURN FNC_LST_OUR_TYPE_T
      PIPELINED;
END;
/
CREATE OR REPLACE PACKAGE BODY pkg
AS
   FUNCTION FNC_LST_OUR (p_code VARCHAR2, p_pm_from VARCHAR2, p_pm_to VARCHAR2)
      RETURN FNC_LST_OUR_TYPE_T
      PIPELINED
   IS
      c          SYS_REFCURSOR;
      v_result   FNC_LST_OUR_TYPE;
   BEGIN
      OPEN c FOR 'select FNC_LST_OUR_TYPE(''AAA'' , ''AW'' , 0 ) from dual
               union all
               select FNC_LST_OUR_TYPE(''AAA'' , ''AQ'' , 5) from dual
               union all
               select FNC_LST_OUR_TYPE(''AAB'' , ''AQ'' , 10) from dual
               union all
               select FNC_LST_OUR_TYPE(''AAA'' , ''CV'', 2) from dual';

      LOOP
         FETCH c INTO v_result;

         EXIT WHEN c%NOTFOUND;
         PIPE ROW (v_result);
      END LOOP;
   END;
END;
/

并使用它:

SELECT * FROM TABLE ( PKG.FNC_LST_OUR ('A', 'B', 'C') )

查看Table Functions

答案 2 :(得分:0)

您可能正在寻找一个返回记录表的流水线函数。为了编写它,你需要一个函数要返回的列的记录类型和行的表类型:

create or replace type fnc_lst_our_record is record(com_code number, pn_code number, our number);
create or replace type fnc_lst_our_table is table of fnc_lst_our_record;

然后使用类型编写函数。顺便说一下,你不需要任何动态SQL。

create or replace function fnc_lst_our
(
  p_code   varchar2,
  p_pm_from  varchar2,
  p_pm_to   varchar2                                  
) return fnc_lst_our_table pipelined is 
begin
  for rec in
  (
    select s.com_code, s.pn_code, count(*) as our   
    from pmtest s 
    inner join pmop_test l on s.com_code = l.com_code and s.pn_code = l.pn_code
    where s.com_code = p_code
    and (p_pm_from is null or p_pm_from s.pn_code between p_pm_from and p_pm_to)
    group by s.com_code,s.pn_code
    having count(s.pn_code) > 0 -- this clause is superfluous
  ) loop
    pipe fnc_lst_our_record(rec.com_code, rec.pn_code, rec.our);
  end loop;  
end;

您完全按照惯例调用此功能。