Bräuchte mal Hilfe mit PL/SQL

Hallo,

wir haben eine Oracle 9.2 Datenbank.

In dieser sind 2 identische Tabellen die LSR und die LSR_TEMP.
beide haben identische Felder.
Funktionsweise: Ein Job sucht Daten aus der Datenbank zusammen und schreibt sie in die LSR_TEMP. gleichzeitig schiebt er die Daten die vollständig sind (Feld Zähler1 und Zähler2 müssen gefüllt sein) in die LSR- Tabelle. von dort aus werden die Daten dann per DB- Link von einer anderen DB zwecks Weiterverarbeitung abgeholt.

Das ganze ist noch in der Testphase, d.h. es werden Daten gezielt generiert die dann mit dem Job abgeholt und verschoben werden.

Das Problem ist nur das er permanent in der DB nach neuen Daten sucht und diese dann verschiebt, ob wir die nun brauchen oder nicht.

Ich hab mir das so gedacht:

man declariert eine tabelle, schreibt dann die ID´s der Daten aus LSR_TEMP in diese virtuelle Tabelle wo Zähler1 und Zähler2 not NULL

dann ließt man nach und nach die ID´s wieder aus und verschiebt dann die passenden Daten in die LSR und löscht dann zum schluß die jeweiligen Daten aus der LSR_TEMP.

die Theorie kenne ich, das das mit Coursor und virtuellen Tabellen geht, aber ich bin noch ganz am Anfang derPL/SQL programmierung.

Ich würde mir den Job auch zurechtbasteln (das müßte ich noch hinbekommen), aber der Job ruft ein Pakage auf und das ist gewrapped

Kann mir da einer Helfen ?

Hallo,

irgendwie verstehe ich noch nicht einmal, wozu Du zwei Tabellen brauchst. Was Du aber mit dem anderen „Job“ meinst, hab ich gar nicht kapiert.

Kannst Du mal etwas genauer definieren, was Dein Problem ist?

Gruß

Peter

ok,

also in die DB laufen permanent Daten rein, Zählerstände.
ein Job sucht den ganzen Kram zusammen und schiebt den in die LSR_TEMP.
dann schaut er nach was in der TEMP drin steht und wenn er zu einer ID alle Info´s gefunden hat (2 Zählerwerte) dann schiebt er die Daten weiter in die LSR. Es kann nämlich vorkommen das ein Zähler abgefragt wird, aber kein Ergebnis zurück kommt.

wir haben jetzt schon alle Daten die wir brauchen in der TEMP- Tabelle und müssen sie jetzt nur noch geordnet rüberschieben.
Den Job können wir dazu nicht gebrauchen, weil der dauernd neue Daten zusammen sucht und deshalb nicht fertig wird (das ist halt in der Testphase, wenn das später mal läuft, dann stehen da nicht auf einen Schlag 15 millionen Datensätze in der TEMP)

ich brauche also ein Script das mir alle kompletten Datensätze raussucht, (where zaehler1 is not NULL and zaehler2 is not NULL) die Zeilen dann in die LSR- Tabelle einfügt und in der TEMP löscht.

Meinem Verständnis nach geht das nur mit PL/SQL, aber mir fehlen die Tiefenkenntnisse um das ding selbst zu bauen.

ich hoffe ich war diesmal verständlicher

Grüße

Chris

Hi Chris
Ein Vorschlag ins Blaue:
Ginge es mit einem Trigger?
Oder muss der Job gezielt ausgelöst werden?
Gruss Ulrich

Hallo Ulrich,

nein, per trigger geht in dem Fall nicht, wir brauchen das ja nur für Tests. später ist der Job der das macht völlig ausreichend, nur jetzt müssen hat so riesen Datenmengen auf einmal verschoben werden.

wie gesagt, ich stell mir das so vor:
select ID from lsr_temp
where zaehler1 is not NULL
and zaehler2 is not NULL;

die id´s müssen halt irgendwo temporär hingeschrieben werden (PL/SQL Tabelle oder sowas) und dann nach und nach wieder rausgeholt und die dazugehörigen Daten in die LSR geschrieben und danach in der LSR_TEMP gelöscht.

Hi Chris
– create tables
create table LSR (id int, z1 int, z2 int);
create table LSR_TEMP (id int, z1 int, z2 int);

– azyklisch fuellen
insert into LSR_TEMP values (1,21292,323);
insert into LSR_TEMP values (2,2889,NULL);
insert into LSR_TEMP values (3,NULL,NULL);
insert into LSR_TEMP values (4,NULL,1267);
update LSR_TEMP set z1=778 where id=3;

– job
insert into LSR (select * from LSR_TEMP where id is not null and z1 is not null and z2 is not null);
delete from LSR_TEMP where id in (select id from LSR);

wobei die ID eindeutig sein muss
set id unique via

  • applikatorisch sicherstellen
  • identity
  • unique constraint
  • key generator
  • sysdate auf kleinster Teilung
    etc.

Versteh ich noch was falsch?
Gruss Ulrich

– job
insert into LSR (select * from LSR_TEMP where id is not null
and z1 is not null and z2 is not null);
delete from LSR_TEMP where id in (select id from LSR);

ja, die ID ist unique…

das ist jetzt schon gemein… irgendwo hab ich mal gelesen das sowas nicht gehen würde weil man beim insert immer nur eine Spalte übergeben könnte… deshalb hab ich mir jetzt so viele gedanken über plsql gemacht…

was mich noch wundert ist normal schreibt man doch „insert into xyz VALUES (…“

ich hatte das mit einer zeile probiert

insert into lsr (id, standort, zaehler1, zaehler2)
values ((select id,standort,zaehler1,zaehler2 from lsr_temp where id = 2));

und bekam dann den Fehler

ORA-00947: Anzahl der Werte reicht nicht aus

das hat mich auch schon irritiert…

jetzt steh ich schon wieder ganz schön dumm da…

Danke dir vielmals !!!

Aber ich werde dann irgendwann trotzdem mal probieren wie man das schön umständlich mit PL/SQL und schleifen und… machen kann :smile:

Grüße

Chris

Hallo Chris!

was mich noch wundert ist normal schreibt man doch „insert
into xyz VALUES (…“

Nicht ganz… Damit das auch etwas sicherer ist schriebt man besser:
INSERT INTO xyz**(c1,c2,c3)** VALUES (val1, val2, val3);

ich hatte das mit einer zeile probiert

insert into lsr (id, standort, zaehler1, zaehler2)
values ((select id,standort,zaehler1,zaehler2 from lsr_temp where id = 2));

und bekam dann den Fehler

ORA-00947: Anzahl der Werte reicht nicht aus

Den Fehler kriegst du deshalb, weil du richtigerweise
INSERT INTO lsr (id, standort, zaehler1, zaehler2) SELECT id,standort,zaehler1,zaehler2 FROM lsr_temp WHERE id = 2;
schreiben hättest sollen…

das hat mich auch schon irritiert…

Wie schon öfter einmal hier zu lesen war (das soll jetzt bitte keine Rüge sein, nur ein kleiner Reminder :wink:): Auf http://tahiti.oracle.com gibt’s die komplette Doku zum Nachlesen. Lediglich eine (Gratis-)Anmeldung im Oracle TechNet ist dafür notwendig…

jetzt steh ich schon wieder ganz schön dumm da…

Hab’ schon schlimmeres gesehen, ehrlich (aber das sind jetzt alles EX-Kollegen von mir *ggg*)

Aber ich werde dann irgendwann trotzdem mal probieren wie man
das schön umständlich mit PL/SQL und schleifen und… machen
kann :smile:

Du kannst BEGIN davor und END dahinter schreiben, dann isses PL/SQL :wink:
Ganz nebenbei wäre das eventuell wirklich zu überdenken, weil das Ganze dann dirket am Server läuft, und nicht unnötigerweise mit ein paar Round-Trips über den Client…

Gruß
Martin

Hallo Martin,

Du kannst BEGIN davor und END dahinter schreiben, dann isses
PL/SQL :wink:
Ganz nebenbei wäre das eventuell wirklich zu überdenken, weil
das Ganze dann dirket am Server läuft, und nicht
unnötigerweise mit ein paar Round-Trips über den Client…

aha, also bei PL/SQL arbeitet der nur auf dem Server… und wieder was dazu gelernt… Danke dir :wink:

Grüße

Chris