如何在Oracle中创建一个可以向其传递参数的视图?

时间:2016-09-10 02:31:31

标签: oracle oracle11g

我在Oracle中创建了一个视图

SELECT *
FROM CUSTOMER
ORDER BY CUSTOMER_ID

这很好用我可以从MyView运行select *。

如何创建一个新视图,我将参数传递给它?
Ex(伪代码):

@LastName = 'Smith';
    SELECT *
    FROM CUSTOMER
    WHERE LAST_NAME = @LastName
    ORDER BY CUSTOMER_ID

1 个答案:

答案 0 :(得分:3)

您无法将参数传递给视图。

通常情况下,查询视图并让优化器处理将谓词推送到最合适的位置就足够了

create view customer_view
as
select *
  from customer

select *
  from customer_view
 where last_name = :lastName
 order by customer_id

您可以编写视图,以便它引用在包变量中设置的值。这有点像黑客,但接近将参数传递给视图

create or replace package my_pkg
as
  g_last_name customer.last_name%type;

  function get_last_name
    return customer.last_name%type;

  procedure set_last_name( p_last_name in customer.last_name%type );
end my_pkg;

create or replace package body my_pkg
as
  procedure set_last_name( p_last_name in customer.last_name%type )
  as
  begin
    g_last_name := p_last_name;
  end;

  function get_last_name
    return customer.last_name%type
  is
  begin
    return g_last_name;
  end;
end;

create or replace view customer_view
as
select *
  from customer
 where last_name = my_pkg.get_last_name;

exec my_pkg.set_last_name( 'Smith' );
select *
  from customer_view
 order by customer_id;

或者您可以定义一个接受参数的流水线表函数,并且可以像表一样查询

create type customer_obj
    as object (
  customer_id integer,
  first_name  varchar2(100),
  last_name   varchar2(100)
);

create type customer_nt
    as table of customer_obj;

create or replace function my_pipeline_function( p_last_name in customer.last_name%type )
  return customer_nt
  pipelined
is
begin
  for c in (select customer_obj( customer_id, first_name, last_name ) customer
              from customer
             where last_name = p_last_name)
  loop
    pipe row( c.customer );
  end loop;
end;

select *
  from table( my_pipeline_function( 'Smith' ))
 order by customer_id;

但是,如果将此管道化表函数连接到其他表,请注意Oracle将无法将任何谓词推送到管道表函数的查询或执行其他转换。并且优化器通常很难猜测特定管道表函数调用将返回多少行,这可能导致它在没有一些工作的情况下选择低于最佳计划的行。这可能会使优化依赖于大量管道表函数的查询变得具有挑战性。