我在Oracle中创建了一个视图
SELECT *
FROM CUSTOMER
ORDER BY CUSTOMER_ID
这很好用我可以从MyView运行select *。
如何创建一个新视图,我将参数传递给它?
Ex(伪代码):
@LastName = 'Smith';
SELECT *
FROM CUSTOMER
WHERE LAST_NAME = @LastName
ORDER BY CUSTOMER_ID
答案 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将无法将任何谓词推送到管道表函数的查询或执行其他转换。并且优化器通常很难猜测特定管道表函数调用将返回多少行,这可能导致它在没有一些工作的情况下选择低于最佳计划的行。这可能会使优化依赖于大量管道表函数的查询变得具有挑战性。