在 Oracle 中,我有一个相当大的 select 语句。我想将其保存为 View ,以便我可以从 .NET 程序调用它并将其用作我们必须生成的一些统计数据的基础。使用 View 时,它始终按日期进行过滤。
我想要这样的东西:
select * from my_view
where my_view.date = '2014-01-01';
问题是我需要在子查询的where条件中使用日期作为参数:
select * from table1
left outer join (
select * from table2
where table2.date = :somedate)
on table1.Id = table2.Id;
...无法将其制作为 View 。
有没有办法可以将日期比较移到子查询之外,而不会弄乱左外连接?
不该做什么:
这会创建一个内部联接 - 这不是我想要的:
select * from table1
left outer join
table2
on table1.Id = table2.Id
where table2.date = '2014-01-01';
此选择过滤掉 table1 中的行,这些行不在指定日期连接到行,但在另一个日期连接到行:
select * from table1
left outer join
table2
on table1.Id = table2.Id
where table2.Id is null
or table2.date = '2014-01-01';
最佳答案
有多种方法可以参数化 View - 例如使用包或应用程序上下文(您可以使用内置上下文 CLIENTCONTEXT)。但所有这些方式都需要对参数的完全控制,并且您必须使用附加功能来设置参数值,这可能是一个严重的缺点:
SQL> create or replace view param_view
2 as
3 select d.name, e.firstname, e.lastname, e.email
4 from department d left join employee e
5 on (d.id = e.departmentid
6 and e.firstname = sys_context('CLIENTCONTEXT','EMPNAME'))
7 /
View created.
SQL> exec dbms_session.set_context('CLIENTCONTEXT','EMPNAME','Scott')
PL/SQL procedure completed
SQL> select * from param_view;
NAME FIRSTNAME LASTNAME EMAIL
-------------------- ---------- -------------------- --------------------
Department A Scott Tiger <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cfb7b7b78fa8a2aea6a3e1aca0a2" rel="noreferrer noopener nofollow">[email protected]</a>
Department B
Department C
SQL> exec dbms_session.set_context('CLIENTCONTEXT','EMPNAME','Allen')
PL/SQL procedure completed
SQL> select * from param_view;
NAME FIRSTNAME LASTNAME EMAIL
-------------------- ---------- -------------------- --------------------
Department A Allen Dirk <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="daa3a3a39abdb7bbb3b6f4b9b5b7" rel="noreferrer noopener nofollow">[email protected]</a>
Department B
Department C
或
SQL> create or replace package pck_test
2 is
3 function get return varchar2;
4 procedure set (x in varchar2);
5 end;
6 /
Package created.
SQL> create or replace package body pck_test
2 is
3 name employee.firstname%type;
4
5 function get return varchar2
6 is
7 begin
8 return name;
9 end;
10
11 procedure set (x in varchar2)
12 is
13 begin
14 name := x;
15 end;
16
17 end;
18 /
Package body created.
SQL> create or replace view param_view
2 as
3 select d.name, e.firstname, e.lastname, e.email
4 from department d left join employee e
5 on (d.id = e.departmentid
6 and e.firstname = pck_test.get)
7 /
View created
SQL> exec pck_test.set('Scott')
PL/SQL procedure completed.
SQL> select * from param_view;
NAME FIRSTNAME LASTNAME EMAIL
-------------------- ---------- -------------------- --------------------
Department A Scott Tiger <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bec6c6c6fed9d3dfd7d290ddd1d3" rel="noreferrer noopener nofollow">[email protected]</a>
Department B
Department C
SQL> exec pck_test.set('Allen')
PL/SQL procedure completed.
SQL> select * from param_view;
NAME FIRSTNAME LASTNAME EMAIL
-------------------- ---------- -------------------- --------------------
Department A Allen Dirk <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="027b7b7b42656f636b6e2c616d6f" rel="noreferrer noopener nofollow">[email protected]</a>
Department B
Department C
SQL> select d.name, e.firstname, e.lastname, e.email
2 from department d left join employee e
3 on (d.id = e.departmentid)
4 /
NAME FIRSTNAME LASTNAME EMAIL
-------------------- ---------- -------------------- --------------------
Department A Allen Dirk <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="97eeeeeed7f0faf6fefbb9f4f8fa" rel="noreferrer noopener nofollow">[email protected]</a>
Department A Scott Tiger <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5d2525251d3a303c3431733e3230" rel="noreferrer noopener nofollow">[email protected]</a>
Department B
Department C
关于sql - 如何将子查询where条件移出子查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23366026/