Daniel Jurak

Daniel Jurak analityk
programista,
architekt danych PKO
BP SA

Temat: [ORACLE] funkcja i execute immediate

witam,
mam taka sytuacje, blok pl/sql wyglada nastepujaco:

declare
v_Data VARCHAR2(8) := '20090101';
begin
execute immediate 'insert into tabela_1 ' ||
'select ' ||
'* ' ||
'from ' ||
'tabela_2 ' || funkcja('XXX');

end


a funkcja zwraca w wyniku taki string
'where data_danych = to_date(v_Data,'rrrrmmdd')'


czyli where tworzony dynamicznie na podstawie tabeli parametrycznej.
jezeli w warunkach where'a nie ma zadnych zmiennych czyli np na sztywno wstawie
w parametrze '= to_date('20090101','rrrrmmdd')' to wszystko smiga.

natomiast problem pojawia sie, jesli chce jeszcze ustawic aby data byla takze zmienna.
pokazuje sie 'ORA-00904: "V_DATA": invalid identifier'

probowalem, takze przenosic date przez argument funkcji, takze nie dziala.

czy gdzies robie blad i powinno to dzialac, czy moze po prostu to nigdy nie bedzie banglac.
Ta wartosc z V_DATA w ktorym momencie powinna być wczytywana do skryptu?

dzieki za odpowiedzi, pozdr.
Grzegorz M.

Grzegorz M. Consultant

Temat: [ORACLE] funkcja i execute immediate

Sproboj przerobic tak, zeby po wywolaniu funkcja XXX zwrocila Ci taki string:
'where data_danych = to_date(' || v_Data || ',''rrrrmmdd'')'

Wtedy dynamiczny sql poskleja Ci stringi, a w miejsce v_Data wrzuci Ci Twoja zmienna.
Daniel Jurak

Daniel Jurak analityk
programista,
architekt danych PKO
BP SA

Temat: [ORACLE] funkcja i execute immediate

Grzegorz M.:
Sproboj przerobic tak, zeby po wywolaniu funkcja XXX zwrocila Ci taki string:
'where data_danych = to_date(' || v_Data || ',''rrrrmmdd'')'

Wtedy dynamiczny sql poskleja Ci stringi, a w miejsce v_Data wrzuci Ci Twoja zmienna.

niestety, przy takim podejsciu dostaje
ORA-01841: (full) year must be between -4713 and +9999, and not be 0

czyli jakby nie uzupelnial tej zmiennej podczas tworzenia stringu.

konto usunięte

Temat: [ORACLE] funkcja i execute immediate

Proponuje sie zapoznać z http://download.oracle.com/docs/cd/B14117_01/appdev.10... , zwłaszcza z częścią na temat using.

A poza tym to konieczne ci to 'execute immediate'?
Takie coś powinno zadziałać szybciej, no chyba ze ex-im jest konieczne z jakiegoś powodu.

insert into tabela_1
select * from tabela_2 where data_danych = to_date(v_Data,'rrrrmmdd');
Tomasz P. edytował(a) ten post dnia 16.04.09 o godzinie 16:06
Daniel Jurak

Daniel Jurak analityk
programista,
architekt danych PKO
BP SA

Temat: [ORACLE] funkcja i execute immediate

Tomasz P.:
zwłaszcza z częścią na temat using.

serdeczne dzieki, juz sobie poprawilem odpowiednio skrypt ;)
A poza tym to konieczne ci to 'execute immediate'?
Takie coś powinno zadziałać szybciej, no chyba ze ex-im jest konieczne z jakiegoś powodu.

no wlasnie, chyba konieczne, poniewaz cale warunek w where jest budowany na podstawie tabeli parametrycznej, i to nie tylko data jak podalem w przykladzie, ale i kilka innych warunkow na pozostalych polach.
Grzegorz M.

Grzegorz M. Consultant

Temat: [ORACLE] funkcja i execute immediate

No faktycznie aby zbudowac dynamicznie to zapytanie z data, to ta funkcja musi juz zwracac stringa z wypelniona data.

Jesli chcesz parametryzowac z bloku kodu, to mozesz do tego uzyc
zmiennych pakietowych - np. cos takiego:

CREATE OR REPLACE PACKAGE pkg_test
IS
-- Parametry
v_Data VARCHAR2(8) := '20090101';

FUNCTION f_test RETURN VARCHAR2;
END pkg_test;
----------
CREATE OR REPLACE PACKAGE BODY pkg_test
IS
FUNCTION f_test RETURN VARCHAR2
IS
vs_sql VARCHAR2(2000);
BEGIN
-- Skladanie warunku
vs_sql:= ' WHERE trunc(sysdate,''DD'') <> to_date('''||pkg_test.v_Data||''',''YYYYMMDD'') ';
RETURN (vs_sql);
END;
END;
---------- Wykorzystanie
declare
vd_sysdate DATE;
vs_sql VARCHAR2(2000);
begin
--- Zmiana paramtetrow
pkg_test.v_Data := '20090415';

--- Skladanie calego zapytania
vs_sql:= 'select sysdate from dual ' || pkg_test.f_test;

execute immediate vs_sql INTO vd_sysdate;
dbms_output.put_line('Wynik zapytania - vd_sysdate: <'||vd_sysdate||'>' );
END;Grzegorz M. edytował(a) ten post dnia 16.04.09 o godzinie 17:21

Następna dyskusja:

[Oracle 10g] execute immedi...




Wyślij zaproszenie do