如何使此查询更通用?

时间:2011-01-13 23:27:11

标签: sql oracle

我有一个问题:

select 
  some_id
from 
  tablename t
where 
  t.end_date < current_date
  and not exists (
    select null
    from tablename ti
    where ti.end_date > t.end_date
      and ti.some_id = t.some_id
      and ti.some_criteria = t.some_criteria
  )

如何更改此设置以便我可以查询任何日期而无需在内部更改查询? (将“current_date”替换为值)

我不是在寻找PL / SQL答案,因为我想把它放在视图中......

3 个答案:

答案 0 :(得分:4)

虽然您说您不想使用PL / SQL,但最好的选择是创建(流水线)表函数。

设置比视图更复杂,但一旦创建,您可以使用“喜欢”带有参数的视图功能:

SELECT *
FROM table(get_stuff(current_date));

以下是一些例子:

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_packages.htm#sthref1054
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/tuning.htm#sthref2351
http://psoug.org/reference/pipelined.html
http://www.oracle.com/technology/sample_code/tech/pl_sql/htdocs/x/Table_Functions_Cursor_Expressions/Pipelined_Table_Functions.htm

答案 1 :(得分:0)

  • 更新#2

此行唯一的日期参数

t.end_date < current_date

因此,您无需更改内部查询即可进行更改。 如果你的意思是

CREATE VIEW v1
as
select 
  some_id
from 
  tablename t
where 
  t.end_date < current_date
  and not exists (
    select null
    from tablename ti
    where ti.end_date > t.end_date
      and ti.some_id = t.some_id
      and ti.some_criteria = t.some_criteria
  )

你希望能够使用这样的东西

select * from v1 where end_date < current_date-7

不确定Oracle是否可以将过滤器内联到视图中,但您可以尝试此操作(删除过滤器)。 虽然函数可能比视图效果更好。

CREATE VIEW v1
as
select 
  some_id
from 
  tablename t
where not exists (
    select null
    from tablename ti
    where ti.end_date > t.end_date
      and ti.some_id = t.some_id
      and ti.some_criteria = t.some_criteria
  )

答案 2 :(得分:0)

您可以使用包变量和包函数以及视图。包变量在会话级别设置,因此对于不同的会话可以是不同的。

创建包规范

create or replace package pkg_current_date is

  current_date date;
  function get_current_date return date;

end pkg_current_date;

包装体:

create or replace package body pkg_current_date is

    function get_current_date return date is

  begin
    return current_date;
  end;


end pkg_current_date;

然后使用您在视图中创建的功能

CREATE VIEW v1
as
select 
  some_id
from 
  tablename t
where 
  t.end_date < pkg_current_date.get_current_date;

要查询视图,只需设置日期然后查询即可。设置某种默认日期可能会付出代价,否则视图将不返回任何内容,因为current_date将为空。

begin
  pkg_current_date.current_date := date '2010-01-01'
end;

select * from v1