
Oracle Forms
Trigger auf Modulebene
WHEN-NEW-FORM-INSTANCE auf Modul Ebene
declare
instanz_name varchar2(64);
begin
select global_name into instanz_name from global_name;
instanz_name := user ||'@'|| instanz_name;
SET_WINDOW_PROPERTY(forms_mdi_window, window_state, maximize);
SET_WINDOW_PROPERTY('window1', window_state, maximize);
-- Setzt den Fenstertitel wie folgt:
-- :Programmtitel Oracleuserid@instanzname
SET_WINDOW_PROPERTY('window1', title, '<'||Get_Application_Property(current_form)||
'>:b e s c h r e i b u n g '||instanz_name);
-- Dynamisch Tabellen- Viewname setzen
-- SET_BLOCK_PROPERTY ('kna_kuli_data',query_data_source_name,'edv.kna_kuli_data_kr');
-- Groß- Kleinschreibung bei exequte_query nicht unterscheiden
set_item_property('block.item' , case_insensitive_query , property_true);
execute_query;
end;
WHEN-TAB-PAGE-CHANGED auf Modul Ebene
declare
curr_tab varchar2(200);
begin
curr_tab := GET_CANVAS_PROPERTY('canvas-name', topmost_tab_page);
commit_io;
if curr_tab = 'tab_page-1' then
go_block('data-block-1');
execute_query;
elsif curr_tab = 'tab_page-2' then
go_block('data-block-2');
execute_query;
elsif curr_tab = 'tab_page-3' then
go_block('data-block-3');
execute_query;
end if;
end;
PRE-TEXT-ITEM auf Modul Ebene
-- feld_focus_an muß als Visuelles Attribut definiert sein
DISPLAY_ITEM(:SYSTEM.TRIGGER_ITEM,'feld_focus_an');
POST-TEXT-ITEM auf Modul Ebene
DISPLAY_ITEM(:SYSTEM.TRIGGER_ITEM,'feld_focus_aus');
ON-LOGON auf Modul Ebene
logon('passwort','user@instanz');
Trigger auf Block- Item Ebene
WHEN-BUTTON-PRESSED auf Block Ebene
call_form('FORMNAME');
exit_form(DO_COMMIT);
pre-query auf Block Ebene
-- WHERE Bedingung für Block setzen
set_block_property('KNA_ORA_MSG',default_where,'where id='||:global.v_id);
-- Sortierung für Block setzen
set_block_property('KNA_ORA_MSG',order_by,'id');
post-query auf Block Ebene
-- Auf dieser Ebene konnen Non Database Items in Abhängigkeit von Database Items gesetzt werden
select bezeichnung into :artikel_bezeichnung from aktikel where artikelnr = :artikelnr;
-- Farbe des Items "ereignis" im Datenblock "fus_ereignis" verändern
-- das Visualle Attribut "vattr_normal" muß definiert sein.
Set_Item_Instance_Property( 'block.Feld', CURRENT_RECORD, VISUAL_ATTRIBUTE,'vattr_normal');
Alerts
Alert
declare
v_alert number(3);
begin
SET_ALERT_BUTTON_PROPERTY('achtung',
ALERT_BUTTON1,
LABEL,
'ja sicher!'); -- ok
SET_ALERT_BUTTON_PROPERTY('achtung',
ALERT_BUTTON2,
LABEL,
'lieber nicht!'); -- abbrechen
set_alert_property('achtung',
title,
'Achtung:');
set_alert_property('achtung',
alert_message_text,
'Alertmeldung');
v_alert := show_alert('achtung');
if v_alert = 88 then
... ok Verarbeitung ...
else
... abbrechen Verarbeitung ...
end if;
end;
Client Dateiname auswählen
:variable := get_file_name('l:\neveling\hpe',null,'mit Semikolon getrennt (*.CSV)|*.csv|');
Datei mit Text-i-o einlesen
PROCEDURE read_file_per_textio ( p_filename in varchar2)
IS
v_imp_file text_io.file_type;
v_imp_record varchar2(2000);
v_rec_cnt number(13);
BEGIN
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'BUSY'); -- Sanduhr ein
v_rec_cnt := 0;
v_imp_file :=text_io.fopen(p_filename,'r'); -- csv-Datei zum Lesen öffnen
text_io.get_line(v_imp_file, v_imp_record); -- Kopfsatz lesen
loop
v_rec_cnt := v_rec_cnt + 1;
-- insert into edv.hpe_imp_dat(ID, LINKCODE, DATENSTROM)
-- values ('', v_linkcode, v_imp_record);
text_io.get_line(v_imp_file, v_imp_record);
end loop;
EXCEPTION
WHEN no_data_found then -- EOF bei text_io.get_line
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'DEFAULT'); -- Sanduhr wieder aus
text_io.FCLOSE(v_imp_file);
WHEN others then
text_io.FCLOSE(v_imp_file);
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'DEFAULT'); -- Sanduhr wieder aus
END read_file_per_textio;
Aufruf LOV per Button
1. Möglichkeit:
-- Auf Feld mit LOV per go_item positionieren
go_item('datenblock.feld');
-- F9 aktivieren
Do_Key('LIST_VALUES');
2.Möglichkeit:
declare a boolean;
begin
a:= show_lov('lov_name');
end;
Dynamisches Sql unter Forms
-- Tabelle anlegen
forms_ddl('create table test2 (id number(13) primary key)');
Package auf Gültigkeit prüfen
PROCEDURE check_package_status IS
/* Die Package Bodys und Heads von 'KKK_EXT_IMPORT',
'FIBU_BUCHUNGEN','FIBU_INPUT','FIBU_OUTPUT','FIBU_TOOLS'
werden auf Gültigkeit über die Tabelle sys.dba_objects
überprüft. Das erste ungültige Package wird per Alert
'alert_inv_pack' (muss in Forms definiert werden) angezeigt. */
v_alert number(3);
v_object_name dba_objects.object_name%type;
v_status dba_objects.status%type;
cursor c_dba_objects is
select object_name, status from dba_objects
where owner = 'EDV'
and substr(object_type,1,7) = 'PACKAGE'
and status <> 'VALID'
and object_name in ('KKK_EXT_IMPORT', 'FIBU_BUCHUNGEN','FIBU_INPUT','FIBU_OUTPUT','FIBU_TOOLS');
begin
open c_dba_objects;
fetch c_dba_objects into v_object_name, v_status;
if c_dba_objects%found then
set_alert_property('alert_inv_pack',alert_message_text,'Package '|| v_object_name||
' ist nicht gültig!');
v_alert := show_alert('alert_inv_pack');
close c_dba_objects;
else
close c_dba_objects;
message('ok');
end if;
END;
Oracle PL/SQL
leerer Block
begin
-- Anweisung
exception
when others then
null;
end;
Funktion (innerhalb eins Packages)
function xxx
( p_linkcode varchar2,
p_wert2 number
)
return number
is
begin
return 0;
exception
when others then
return null;
end xxx;
-- deterministic Function für Indexfelder
CREATE OR REPLACE FUNCTION XXXF_pro_date(p_date date) return date deterministic
is
begin
if to_char(p_date,'HH24MI') >= '2230' then
return p_date + 1;
end if;
return p_date;
exception
when others then
return p_date;
end;
/
Null Wert auf 0 setzen
numvar := nvl(numvar, 0);
aktuelle DB ermitteln
select global_name from global_name
Monats letzten ermitteln
-- Eingabe 01.10.2002 als '011002'
-- Ergebnis : Datefeld 31.10.2002
select last_day(to_date('01'||'1002','DDMMYY')) from dual;
Heute vor einem Jahr
select add_months(sysdate, -12) from dual;
einen Monat zurück
select add_months(sysdate, -1) from dual;
Die Kalenderwoche zu eimem Datum ermitteln
select to_char(sysdate,'iw') from dual;
Den Wochentag zu eimem Datum ermitteln
-- Wochentag
-- das Ergebnis hängt von den nlslang Einträgen in der Regitry ab!
-- Mit trim werden evtl. rechtsstehende Leerzeichen gelöscht!
select trim(to_char(sysdate,'day')) from dual;
1.1. des laufenden Jahres
select trunc(sysdate,'YY') from dual
1. des laufenden Monats
select trunc(sysdate,'MM') from dual;
Anfang des Quartals
select trunc(sysdate,'Q') from dual;
Anfang der Woche (Montag)
select trunc(sysdate,'D') from dual;
Cursor
cursor c_lieferant (p_lieferant NUMBER) IS
select kund_id
from ku
where kund_id = p_lieferant
order by xxx;
r_lieferant c_lieferant%rowtype;
b_lieferant boolean;
begin
open c_lieferant (:block3.lieferant);
fetch c_lieferant into r_lieferant;
b_lieferant := c_lieferant%found;
close c_lieferant;
end;
Prozentanzeige im Cursorloop bei Abarbeiten einer Tabelle
rec_num number(13);
proz number(13,2);
proz_z number(13,2);
rec_gesamt number(13);
BEGIN
rec_num := 0;
select count(*) into rec_gesamt from &tabelle where &where&;
proz_z := 0;
-- open cursor;
-- fetch cursor into ...
-- while cursor%found
loop
rec_num := rec_num + 1;
proz := rec_num * 100 / rec_gesamt;
if proz - proz_z >= 5 or proz >= 99.5 then
SYNCHRONIZE;
message(proz||' % Daten ('||rec_num||' Sätze) importiert',NO_ACKNOWLEDGE);
SYNCHRONIZE;
proz_z := proz;
end if;
-- Fetch cursor into ...
end loop;
-- close cursor;
end;
Linkcode (eindeutige Laufkennung z.B. für Schnittstellen) erzeugen
declare
v_linkcode varchar2(13);
begin
-- Linkcode aus Datum Uhrzeit erzeugen
v_linkcode := to_char(sysdate,'YYMMDDHH24MISS');
end;
genauer geht's wie folgt
declare
v_linkcode varchar2(17);
begin
-- Linkcode aus Datum Uhrzeit bis auf 1/1000 sec. erzeugen erzeugen
v_linkcode := to_char(systimestamp,'YYYYMMDDHH24MISSff3');
end;
nocht genauer mit sessionid:
declare
v_linkcode varchar2(24);
begin
v_linkcode := to_char(systimestamp,'YYYYMMDDHH24MISSff3')||'_'||sys_context('USERENV', 'SESSIONID');
end;
select to_char(systimestamp,'YYYYMMDDHH24MISSff3')||'_'||sys_context('USERENV', 'SESSIONID') from dual;
20080917185009351_920534
select to_char(systimestamp,'YYYYMMDDHH24MISSff3')||'_'||sys_context('USERENV', 'OS_USER')||'_'||sys_context('USERENV', 'SESSIONID') from dual;
20080917184945343_gregor.neveling_920534
Foreign Key auf Mastertabelle (Referenzielle Integrität)
-- Detailtabelle anlegen
CREATE TABLE TDETAIL (ID NUMBER (13), MASTERID NUMBER (13), FELD3 VARCHAR2 (100))
TABLESPACE KNA_EDV STORAGE (INITIAL 1m NEXT 1m MAXEXTENTS unlimited);
ALTER TABLE TDETAIL ADD CONSTRAINT FK_TMASTER
FOREIGN KEY (MASTERID) -- Key der Detailtabelle
REFERENCES TMASTER (ID) ; -- Referenzkey in der Master Tabelle (ID muß Primary Key von TMaster sein)
Rechte für Delete/Insert/Select & Update für anderen User (hope) zulassen
GRANT DELETE ON KNA_IMPHEAD TO HOPE;
GRANT INSERT ON KNA_IMPHEAD TO HOPE;
GRANT UPDATE ON KNA_IMPHEAD TO HOPE;
GRANT SELECT ON KNA_IMPHEAD TO HOPE;
oder noch einfacher:
grant all on {tabelle} to {user/Rolle} [with grantoption]
Kommentar für eine Tabellenspalte setzen
COMMENT ON COLUMN KNA_IMPHEAD.ANZAHL IS 'Anzahl Datensätze aus dem Loader';
Kommentar für eine Tabelle setzen
COMMENT ON TABLE KNA_IMP_REFERENZ IS 'Feldzuordnung mit Typengerechter Konvertierung';
Public Synonym KNA_IMPHEAD für die Tabelle EDV.KNA_IMPHEAD
CREATE PUBLIC SYNONYM KNA_IMPHEAD FOR EDV.KNA_IMPHEAD;
Logfile per utl_file schreiben
create procedure write_logfile_demo
is
diskfile utl_file.file_type;
v_path varchar2(2000) := '/knauberT/dta/CK8T/export';
begin
-- Datei "logfile_YYYYMMDD" wird append geöffnet und schreibt des Satz "Hello World" hinein
diskfile := utl_file.fopen(rtrim(v_path),'logfile_'||to_char(sysdate,'YYYYMMDD'),'a',32767);
utl_file.put_line (diskfile,'Hello World');
utl_file.fclose(diskfile);
exception
when utl_file.invalid_path then (...)
when utl_file.invalid_mode then (...)
when utl_file.invalid_filehandle then (...)
when utl_file.invalid_operation then (...)
when utl_file.read_error then (...)
when utl_file.write_error then (...)
when utl_file.internal_error then (...)
when no_data_found then (...)
when value_error then (...)
when others then (...)
end;
Datei vom Server per utl_file einlesen
/*****************************************************************************************
Das Verzeichnis p_dir muß für utl_file freigegeben (Datei init.ora bis Version 8) sein.
z.B. Verzeichis c:\utlfile auf dem Oracle Server anlegen und
utl_file_dir=c:\utlfile
in die Datei init.ora einfügen
Für 9i unter Unix gilt:
SQL> CREATE DIRECTORY log_dir AS '/appl/gl/log';
Für 9i unter Windows gilt:
SQL> CREATE DIRECTORY log_dir AS 'c:\temp';
Das Verzeichnis muß existieren und entsprechende Rechte für den User 'ORACLE' haben.
SQL> GRANT READ ON DIRECTORY log_dir TO DBA;
SQL> GRANT WRITE ON DIRECTORY log_dir TO DBA;
SQL> GRANT ALL ON DIRECTORY log_dir TO userid;
Achtung!
Auf Verzeichnisse die unter dem benannten Verzeichnis liegen kann nicht zugegriffen werden.
*******************************************************************************************/
procedure arc_protokolle (p_dir varchar2,
p_file varchar2,
)
is
diskfile utl_file.file_type;
v_rec varchar2 (32767);
v_lfd number (8);
begin
diskfile := utl_file.fopen (p_dir, p_file, 'r', 32767);
v_lfd := 0;
loop
begin
utl_file.get_line (diskfile, v_rec);
v_lfd := v_lfd + 1;
(... v_rec verarbeiten ...)
exception
when no_data_found
then
exit;
end;
end loop;
utl_file.fclose (diskfile);
exception
when utl_file.invalid_path then (...)
when utl_file.invalid_mode then (...)
when utl_file.invalid_filehandle then (...)
when utl_file.invalid_operation then (...)
when utl_file.read_error then (...)
when utl_file.write_error then (...)
when utl_file.internal_error then (...)
when no_data_found then (...)
when value_error then (...)
when others then (...)
end;
Autonome Transkation PROCEDURE put_line(p_text varchar2)
--
-- alternative zu dbms_output.put_line - schreibt Text als autonome Transaktion in die Tabelle kna_msg
--
is
PRAGMA AUTONOMOUS_TRANSACTION;
begin
insert into kna_msg(TEXT, TIMESTAMP) values (p_text, sysdate);
commit;
END;
Forms Zeilenweise bearbeiten
declare
v_alert number(3);
begin
set_alert_property('loesch_abfrage',alert_message_text,'Wollen Sie alle markierten Schnittstelle wirklich löschen?');
v_alert := show_alert('loesch_abfrage');
if v_alert = 88 then
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'BUSY');
first_record;
while :system.last_record = 'FALSE'
loop
...
next_record;
end loop;
last_record;
...
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'DEFAULT'); -- Sanduhr aus
execute_query;
end if;
end;
Non Database Felder füllen
im Trigger WHEN-NEW-RECORD-INSTANCE auf Datenblock Ebene:
first_record;
while :system.last_record = 'FALSE'
loop
if nvl(:filiale, 0) <> 0 then
:filial_bez := F_KNA_FILIAL_BEZ(:filiale);
else
:filial_bez := '';
end if;
next_record;
end loop;
last_record;
if nvl(:filiale, 0) <> 0 then
:filial_bez := F_KNA_FILIAL_BEZ(:filiale);
else
:filial_bez := '';
end if;
first_record;
Generierung eines SQL Statements für alle Tabellen eines Schemas
-- Die Tabelle/View all_tables enthält in der Spalte TABLE_NAME die Tabellennamen
-- Hier wird für alle Tabellen des Owners EDV, die im Namen mit FUS_ beginnen ein
-- public Synonym gebildet.
-- Els Ergebnis wird der Text eines SQL zum erzeugen der Synonyme erzeugt.
select 'CREATE PUBLIC SYNONYM '||TABLE_NAME
||' for '||TABLE_NAME from all_tables where owner = 'EDV' and table_name like 'FUS_%';
Systemmeldung bei commit unterdrücken
PROCEDURE commit_io IS
oldmsg VARCHAR2(2);
BEGIN
oldmsg := :System.Message_Level;
:System.Message_Level := '10';
commit;
:System.Message_Level := oldmsg;
EXCEPTION
WHEN Form_Trigger_Failure THEN
:System.Message_Level := oldmsg;
END commit_io;
Dynamische Befehl aus PL/SQL per EXECUTE IMMEDIATE
declare
sql_stat varchar2(2000);
emp_rec kna_centralvoucher.voucherno%rowtype;
v_voucherno kna_centralvoucher.voucherno%type;
begin
sql_stat := 'truncate table kna_centralvoucher';
EXECUTE IMMEDIATE (sql_stat);
sql_stat := 'insert into kna_centralvoucher (select voucherno - 99000000000000000000 from ads_centralvoucher)';
EXECUTE IMMEDIATE (sql_stat);
EXECUTE IMMEDIATE 'CREATE TABLE bonus (id NUMBER, amt NUMBER)';
sql_stat := 'INSERT INTO kna_centralvoucher (voucherno) VALUES (:1)';
EXECUTE IMMEDIATE sql_stat USING v_voucherno;
sql_stat := 'SELECT * FROM kna_centralvoucher WHERE voucherno = :1';
EXECUTE IMMEDIATE sql_stat INTO emp_rec USING v_voucherno;
commit;
end;
CREATE OR REPLACE function dyn_sel(p_tab varchar2
, p_feld varchar2
, p_where varchar2
, p_groupby varchar2
, p_orderby varchar2)
return varchar2
-- select dyn_sel('unitrade_kon','konf_nr||'';''||konf_wert','nvl(konf_nr,999)<87',null,'konf_nr desc') erg from dual;
is
sql_stat varchar2(2000);
v_val varchar2(2000);
begin
sql_stat := 'SELECT '||p_feld||' FROM '||p_tab||' WHERE rownum = 1';
if p_where is not null then
sql_stat := sql_stat || ' and '||p_where;
end if;
if p_groupby is not null then
sql_stat := sql_stat || ' group by '||p_groupby;
end if;
if p_orderby is not null then
sql_stat := sql_stat || ' order by '||p_orderby;
end if;
EXECUTE IMMEDIATE sql_stat INTO v_val;
return v_val;
exception
--Fehlerausgabe wenn SQL-Fehler:
--error function dyn_sel "SELECT koxnf_wert FROM unitrade_kon WHERE rownum = 1 and konf_nr=87"
--ORA-00904: "KOXNF_WERT": invalid identifier
when others then return 'error function dyn_sel "'||sql_stat||'"'||chr(13)||chr(10)||sqlerrm;
end;
/
Dynamische Select per Ref Cursor
Testfunktion:
CREATE OR REPLACE FUNCTION test_dyn_select(p_select IN VARCHAR2)
RETURN varchar2
IS
TYPE cv_type IS REF CURSOR;
cv cv_type;
v_wert VARCHAR2 (32767);
BEGIN
OPEN cv FOR p_select;
FETCH cv INTO v_wert;
CLOSE cv;
RETURN v_wert;
EXCEPTION
WHEN OTHERS
THEN
return('*** Fehler ***'||sqlerrm);
end;
Test:
select test_dyn_select('select count(*) from kna_imphead') from dual;
--------------------------------------------------------------------------------
10170
1 row selected
Variable mit fester Länge und links- oder rechsbündiger Ausrichtung
CREATE OR REPLACE function fixStr(p_ausr char, p_len number, p_str varchar2) return varchar2 is
--
-- Funktion zur Ausrichtung von Feldern für Ausgabedateien
-- Parameter:
-- p_ausr: R: Rechtsbündige Ausrichtung, links wird mit 0 aufgefüllt
-- L: Linksbündige Ausrichtung, rechts werden Leerzeichen aufgefüllt
-- p_len Länge des ausgabefeldes in Bytes
-- p_str Feldinhalt der ausgerichtet werden soll
-- Beispiel:
-- select fixstr('L',10, '1')||'*' from dual; --> "1 *"
-- select fixstr('R',10, '1')||'*' from dual; --> '0000000001*'
v_str varchar2(2000);
begin
if upper(nvl(p_ausr,' ')) <> 'R' then
if length(p_str) < p_len then
v_str := rpad(p_str,p_len);
else
v_str := substr(p_str, 1, p_len);
end if;
else
if length(p_str) < p_len then
v_str := lpad(p_str,p_len,'0');
else
v_str := substr(p_str, 1, p_len);
end if;
end if;
return v_str;
end;
/
Umwandlung Varchar2 in Zahl mit NLS_NUMERIC_CHARACTERS
v_rab_proz := to_number(substr('02,50 xx', 1, 5), '99D99', 'NLS_NUMERIC_CHARACTERS = '',.''');