在oracle11g中创建参数化视图

pri*_*dev 14 oracle views oracle11g

我有一个很大的查询与嵌套和左连接和Ineed创建一个视图,以便不从应用程序运行它.问题是我需要日期范围和其他一些字段作为输入参数,因为它会因每个请求的前端而异.我只是查了一下并看到一些帖子指的是使用SYS_CONTEXT进行参数化视图,并且需要确切地知道如何创建视图,例如使用2个参数 - fromdate, todate以及我如何从应用程序调用视图.

仅供参考我使用grails/groovy来开发应用程序.这是我想要创建视图的查询..

 select 
    d.dateInRange as dateval,
    eventdesc,
    nvl(td.dist_ucnt, 0) as dist_ucnt
from (
    select 
        to_date(fromdate,'dd-mon-yyyy') + rownum - 1 as dateInRange
    from all_objects
    where rownum <= to_date(fromdate,'dd-mon-yyyy') - to_date(todate,'dd-mon-yyyy') + 1
) d
left join (
    select 
        to_char(user_transaction.transdate,'dd-mon-yyyy') as currentdate,
        count(distinct(grauser_id)) as dist_ucnt,
        eventdesc 
    from
        gratransaction, user_transaction 
  where gratransaction.id = user_transaction.trans_id and 
  user_transaction.transdate between to_date(fromdate,'dd-mon-yyyy') and to_date(todate,'dd-mon-yyyy') 
    group by  to_char(user_transaction.transdate, 'dd-mon-yyyy'), eventdesc 
) td on td.currentdate = d.dateInRange order by d.dateInRange asc
Run Code Online (Sandbox Code Playgroud)

Jef*_*emp 15

这里描述了上下文方法:http://docs.oracle.com/cd/B28359_01/network.111/b28531/app_context.htm

例如(从上面的链接改编的例子)

CREATE CONTEXT dates_ctx USING set_dates_ctx_pkg;

CREATE OR REPLACE PACKAGE set_dates_ctx_pkg IS 
  PROCEDURE set(d1 in date, d2 in date); 
END; 
/

CREATE OR REPLACE PACKAGE BODY set_dates_ctx_pkg IS
  PROCEDURE set(d1 in date, d2 in date) IS 
  BEGIN 
    DBMS_SESSION.SET_CONTEXT('dates_ctx', 'd1', TO_CHAR(d1,'DD-MON-YYYY'));
    DBMS_SESSION.SET_CONTEXT('dates_ctx', 'd2', TO_CHAR(d2,'DD-MON-YYYY'));
  END;
END;
/
Run Code Online (Sandbox Code Playgroud)

然后,在应用程序中设置日期:

BEGIN set_dates_ctx_pkg.set(mydate1, mydate2); END;
/
Run Code Online (Sandbox Code Playgroud)

然后,使用以下方法查询参数:

SELECT bla FROM mytable
WHERE mydate
  BETWEEN TO_DATE(
            SYS_CONTEXT('dates_ctx', 'd1')
          ,'DD-MON-YYYY')
      AND TO_DATE(
            SYS_CONTEXT('dates_ctx', 'd2')
          ,'DD-MON-YYYY');
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是它非常适合查询; 它在运行时不涉及DDL或DML,因此没有任何事务需要担心; 它非常快,因为它不涉及SQL-PL/SQL上下文切换.

或者:

如果您无法使用上下文方法和John的包变量方法,则另一种方法是将参数插入表中(例如,如果您在同一会话中运行查询,则为全局临时表),然后加入该表从视角来看.缺点是您现在必须确保运行一些DML以在需要运行查询时插入参数.

  • *为什么*你不能使用程序,功能或包?如果您使用的是Oracle,则没有充分的理由让您避免使用它们. (3认同)

Nec*_*eco 7

我刚刚为这个恼人的Oracle劣势做了一个解决方法.像这样

create or replace package pkg_utl
as
  type test_record is record (field1 number, field2 number, ret_prm_date date);
  type test_table is table of test_record;
  function get_test_table(prm_date date) return test_table pipelined;
end;
/

create or replace package body pkg_utl
as
  function get_test_table(prm_date date) return test_table pipelined
  is
  begin
    for item in (
      select 1, 2, prm_date
      from dual
    ) loop
      pipe row (item);
    end loop;
    return;
  end get_test_table;
end;
/
Run Code Online (Sandbox Code Playgroud)

它仍然需要一个包,但至少我可以更方便地使用它:

select *
from table(pkg_utl.get_test_table(sysdate))
Run Code Online (Sandbox Code Playgroud)

我不确定表现......