Dynamische Where Klausel in SP von Oracle

Hallo,

ich nutze Oracle 10g und habe eine Frage.

Kann man in einer Where Bedingung Teile dynamisch halten.

Angenommen ich habe einen Eingangswert mit Namen „input_Name“.

Wenn der Wert leer ist soll er den Teil der Where Bedingung icht machen andernfalls schon.

Hier ein Bsp. (nicht lauffähigf sondern nur sinnbildlich

select *
from tTabelle1 t
where
Ort = „Berlin“
if t.Name „“ then
AND t.Vorname = input_Name
end if

Kann ich die Bedingung des Namens dynamisch gestalten oder muss ich 2 Prozeduren anlegen.

Einmal für :
… where
Ort = „Berlin“
AND t.Vorname = input_Name

und einmal für :
… where
Ort = „Berlin“

Danke im vorraus
Martin

Hi!

Kann man in einer Where Bedingung Teile dynamisch halten.

Natürlich.

Angenommen ich habe einen Eingangswert mit Namen „input_Name“.
Hier ein Bsp. (nicht lauffähigf sondern nur sinnbildlich

Von welchem Objekt sollte das der Eingangswert sein? DAS ist hier besonders wichtig!

select *
from tTabelle1 t
where
Ort = „Berlin“
if t.Name „“ then
AND t.Vorname = input_Name
end if

Ich verstehe noch immer nicht, was Du eigentlich genau willst.

Kann ich die Bedingung des Namens dynamisch gestalten oder
muss ich 2 Prozeduren anlegen.

Dir ist der Name „Prozedur“ unter Oracle nicht gerade geläufig, stimmt’s?

Werde konkreter und Hilfe sei Dir gegeben.

Grüße,
Tomh

Hi,

Okay… ich versuchs nochmal zu erklären.

Ich möchte folgende Procedure vereinfachen.
Die realen Selects sind weitaus umfassender und unterscheiden sich, wie im Bsp., nur um „AND Spalte2 = parameter2“

create or replace PROCEDURE sp_Abfrage1
(
parameter1 in varchar2,
parameter2 in varchar2,
result out number,
) as
Begin

if(parameter2 ‚egal‘) then
SELECT Count(*) into result
FROM Tabell1 t
WHERE
Spalte1 = parameter1;
else
SELECT Count(*) into result
FROM Tabell1 t
WHERE
Spalte1 = parameter1
AND
Spalte2 = parameter2;
end if;

End;

mfg
Martin

Hi!

Ich möchte folgende Procedure vereinfachen.

Ach so … Stichwort: EXECUTE IMMEDIATE

(Ich „korrigiere“ nur den zu korrigierenden Code)

create or replace PROCEDURE sp_Abfrage1
(
parameter1 in varchar2,
parameter2 in varchar2,
result out number,
) as

stmt varchar2(2000) := 'select count(\*) from tabell1
where spalte1='''||parameter1||''';

Begin

if(parameter2 ‚egal‘) then

null; -- bin zu faul, um das IF "umzudrehen" :wink: 

else

stmt := stmt || ' and Spalte2 = '''||parameter2||''';

end if;

execute immediate stmt into v\_result;

End;

Grüße,
Tomh

Nochmals Hi!

Kurzer Zusatz noch:

Natürlich kann man auch die Parameter als (Binde-)Variablen an das Statement übergeben, damit der Parser etwas schneller wird.

Grüße,
Tomh

Hallo!

Man kann das auch alles in den select packen…
also da gibts mal den decode…
select decode(spalte, wert1, result1, result2) from dual

den kann man in etwa so lesen:
wenn spalte==wert1 dann liefere result1, sonst liefere result2
weiters kann man das noch weiter schachteln:
decode(spalte, wert1, result1, decode(spalte, wert2, result2, defaultwert))

also pseudocode würde für den decode so aussehen:

function decode(param1, param2, param3, param4)
begin
if param1==param2 then
return param3;
elsif
return param4;
end if;
end;

weiters kannst du auch noch default-werte in die where-bedingung einfügen:

select werte from tabelle
where (nvl(:bINPUTVAR, 0)=0 or :bINPUTVAR=spaltenname)

was hier gemacht wird:
die bindvariable „:bINPUTVAR“ muss entweder eben der spalte entsprechen oder 0 oder NULL sein (nvl verwandelt null in den zweiten parameter, also in diesem Fall 0).
Dabei musst du aber vorsichtig sein, wenn es dann um Performance geht. Oracle kann so eine Where-klausel nicht richtig auflösen, d.h. ein Datenbank-Index greift dann nicht!

Alles in allem kann man damit sehr viele schweinereien anfangen, man muss nur immer aufpassen, wie das performt.
In einer where eine function aufrufen würde ich mir auch sehr überlegen, weil das die Komplexität in der function versteckt. Wenn jetzt ein Select 5000 Datensätze bringt, wird diese function 5000x ausgeführt… also wirklich mit vorsicht genießen!

hoffe, ich hab dich nicht allzu sehr verwirrt :smile:

  • na ja der Parser wird nicht schneller, er parst nur weniger, aber man kann dies nicht nur so machen , sondern MUSS es so tun !

Gruss :smile:

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi!

  • na ja der Parser wird nicht schneller, er parst nur weniger,
    aber man kann dies nicht nur so machen , sondern MUSS es so
    tun !

Ähm, natürlich - er muß halt keinen Ausführungsplan mehr erstellen (sofern das Statement noch im Library Cache liegt) - und das kann sehr, sehr, sehr viel Zeit bringen.

Grüße,
Tomh

PS: Ist die SGA zu klein definiert, nutzen auch keine Bindevariablen mehr was …