2011-01-13 16 views
0

Ich habe eine Abfrage:Wie kann ich diese Abfrage allgemeiner machen?

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 
) 

Wie kann ich das ändern, so dass ich es für ein beliebiges Datum abfragen können, ohne die Abfrage auf der Innenseite ändern zu müssen? (Ersetzen Sie die "current_date" mit einem Wert)

Ich bin nicht auf der Suche nach einer PL/SQL-Antwort, wie ich dies in einer Ansicht setzen will ...

+0

Sie meinen, Sie möchten nur das Datum angeben, wenn Sie eine Abfrage für die Ansicht ausführen?Dann müssen Sie das 'end_date

+0

Eine Ansicht ist nicht wie eine Funktion. Sie können keine Parameter in eine Sicht übergeben. Die Ansicht enthält eine feste Abfrage, die ihr Verhalten nicht von irgendeiner Art von Eingabe abhängig machen kann. Sie werden eine gespeicherte Prozedur benötigen, um das zu erreichen, was Sie wollen. –

+0

Ja, die Umgebung, in der ich arbeite, ist super paranoid über pl/sql procs, und mir wurde gesagt, ich solle versuchen, es als eine Ansicht für Datum n arbeiten zu lassen. Dies zu ändern, sollte wirklich einfach sein, es ist einfach nicht die Lösung, die der Stakeholder bevorzugt. –

Antwort

4

Obwohl Sie sagen, Sie wollen nicht, PL/SQL verwenden, wäre die beste Option sein, eine (pipelined) Tabellenfunktion zu erstellen.

Es ist ein bisschen mehr zu Setup kompliziert als eine Ansicht, aber einmal erstellt, können Sie die Funktion „wie“ eine Ansicht mit Parametern verwenden:

 
SELECT * 
FROM table(get_stuff(current_date)); 

Hier sind einige Beispiele:

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

+0

Wie funktionieren Tabellenfunktionen gegen Sichten oder Unterabfragen? –

+0

Sie sind ein bisschen langsamer, denke ich, aber es hängt davon ab, was genau du tust. –

+0

Dies ist die beste Lösung, es dauerte nur eine Weile, um es dem Stakeholder zu erklären. Die Links helfen. –

0
  • AKTUALISIERT # 2

Der einzige Zeitpunkt Parameter auf dieser Linie gibt es

t.end_date < current_date 

So ist alles, was Sie ohne Änderung der inneren Abfrage ändern müssen. Wenn Sie meinen, dass die Sicht ist

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 
) 

Und Sie wollen in der Lage sein, etwas wie dieses

select * from v1 where end_date < current_date-7 

Nicht sicher zu verwenden, wenn Oracle den Filter in der Ansicht Inline können, aber Sie können versuchen, diese (Entferne den Filter). Eine Funktion funktioniert möglicherweise besser als eine Ansicht.

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 
) 
+0

Ich stimme zu. Ich sehe nichts in der Sub-Abfrage, die geändert werden müsste –

+0

Das OP sagt, dass er * 'current_value' * nicht ersetzen will, wenn er die Abfrage aufruft, damit es in eine Ansicht gehen kann. –

+0

djacobson ist korrekt, wenn ich es auf das obige ändere, bekomme ich immer das zuletzt beendete t (ich merke, dass dies den current_date Filter in der äußeren Abfrage meistens irrelevant macht) unabhängig davon, was ich als gefiltert habe. –

0

Sie können eine Paketvariable und eine Paketfunktion zusammen mit der Ansicht verwenden. Die Paketvariable wird auf Sitzungsebene festgelegt und kann daher für verschiedene Sitzungen unterschiedlich sein.

Erstellen Sie das Paket spec

create or replace package pkg_current_date is 

    current_date date; 
    function get_current_date return date; 

end pkg_current_date; 

Und das Paket Körper:

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; 

dann die Funktion, die Sie innerhalb einer Ansicht erstellt verwenden

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

die Ansicht abzufragen, gerade eingestellt das Datum und dann abfragen. Es würde sich wahrscheinlich lohnen, eine Art Standarddatum festzulegen, ansonsten wird die Ansicht nichts zurückgeben, da current_date null ist.

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

select * from v1 
Verwandte Themen