简体   繁体   English

oracle是使用函数的表的结果

[英]oracle results from tables using function

I'm doing some testing to see if I can speed up a particular result set, but can't seem to get this particular solution working. 我正在做一些测试,看看我是否可以加速特定的结果集,但似乎无法使这个特定的解决方案正常工作。 I have data coming a few different tables and want to combine the data. 我有数据来自几个不同的表,并希望结合数据。 I want to try this without using a union select to see if I get a performance improvement. 我想尝试这个,而不使用联合选择,看看我是否得到了性能提升。

When I have a custom table/object type in a function, it seems to delete the existing data from the table when doing the subsequent select. 当我在函数中有自定义表/对象类型时,它似乎在执行后续选择时从表中删除现有数据。 Is there a way to do subsequent selects into the table without having the previous data deleted? 有没有办法在不删除先前数据的情况下对表进行后续选择?

SQL Fiddle SQL小提琴

I don't think that approach will be faster, in fact I expect it to be much slower. 我不认为这种方法会更快,事实上我认为它会慢得多。

But if you do want to do it, you need to put the rows from the second select into an intermediate collection and then join both using multiset union . 但是如果你想这样做,你需要将第二个select中的行放入一个中间集合中,然后使用multiset union加入它们。

Something like this: 像这样的东西:

create or replace function
  academic_history(p_student_id number)
  return ah_tab_type
  is
  result ah_tab_type;
  t ah_tab_type;
begin

  select ah_obj_type(student_id,course_code,grade)
     bulk collect into result
  from completed_courses
  where student_id = p_student_id;

  select ah_obj_type(student_id,course_code,'P')
    bulk collect into T
  from trans_courses
  where student_id = p_student_id;

  result := result multiset union t;

  return result;
end;
/

As well as the multiset approach, if you really wanted to do this you could also make it a pipelined function : 除了multiset方法,如果你真的想要这样做,你也可以使它成为一个流水线函数

create or replace function
academic_history(p_student_id number)
return ah_tab_type pipelined
is
    T ah_tab_type;
begin
    select ah_obj_type(student_id,course_code,grade)
    bulk collect
    into T
    from completed_courses
    where student_id = p_student_id;

    for i in 1..T.count loop
        pipe row (T(i));
    end loop;

    select ah_obj_type(student_id,course_code,'P')
    bulk collect
    into T
    from trans_courses
    where student_id = p_student_id;

    for i in 1..T.count loop
        pipe row (T(i));
    end loop;

    return;
end;

SQL Fiddle . SQL小提琴

Thanks a_horse_with_no_name for pointing out that doing the multiple selects one at a time will probably be slower. 感谢a_horse_with_no_name指出一次多次选择一个可能会慢一些。 I was able to reduce the execution time by filtering each select by student_id and then union-ing (rather than union-ing everything then filtering). 通过student_id过滤每个选择然后联合(而不是联合所有内容然后过滤),我能够减少执行时间。 On the data set I'm working with this solution was the fastest taking less than 1/10 of a second... 在数据集上我正在使用这个解决方案是最快的,不到1/10秒......

create or replace function
  academic_history(p_student_id number)
  return ah_tab_type
  is
  T ah_tab_type;
begin

  select ah_obj_type(student_id,course_code,grade)
  bulk collect
  into T
  from (
    select student_id,course_code,grade
    from completed_courses
    where student_id = p_student_id
    union
    select student_id,course_code,'P'
    from trans_courses
    where student_id = p_student_id);

  return T;
end;
/
select *
from table(academic_history(1));

and this took 2-3 seconds to execute... 这需要2-3秒才能执行......

create view vw_academic_history
select student_id,course_code,grade
from completed_courses
union
select student_id,course_code,'P'
from trans_courses;

select *
from vw_academic_history
where student_id = 1;

SQLFiddle . SQLFiddle

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM