Zum Inhalt springen

oracle datenbank help


 Teilen

Empfohlene Beiträge

einen wunderschönen guten morgen,

 

kennt sich vl wer a bissl mit oracle datenbanken aus?

 

ich will ein paar trigger in packages zusammenfassen...

 

CREATE TRIGGER TRG_Bike
   BEFORE INSERT OR UPDATE ON Bike
   FOR EACH ROW
DECLARE
   iAUTONUMBER BIKE.IDBIKE%TYPE;
   cannot_change_AUTONUMBER EXCEPTION;
BEGIN
   IF INSERTING THEN
   SELECT trig.NEXTVAL INTO iAUTONUMBER FROM DUAL;
   :new.IDBIKE := iAUTONUMBER;
   END IF;

   IF UPDATING THEN
       IF NOT(:new.IDBIKE = :old.IDBIKE) THEN
           RAISE cannot_change_AUTONUMBER;
       END IF;
   END IF;
EXCEPTION
   WHEN cannot_change_AUTONUMBER THEN
   raise_application_error (-20000, 'AUTONUMBER KANN NICHT GEÄNDERT WERDEN');
END;

 

das is mein trigger, eh standardmässig....

....nur

 

mein package:

CREATE OR REPLACE PACKAGE "4CIDOMKIS"."myPackage"
AS
 FUNCTION 
   ( [ IN | OUT | NOCOPY [ ... ]]
 [])
   RETURN ;
 PROCEDURE 
   ( [ IN | OUT | NOCOPY [ ... ]]
 []);
END;

 

hat wer ahnung davon? :f:

 

lg

dominik

Link zu diesem Kommentar
Auf anderen Seiten teilen

was willst du denn machen ?

irgendwie fehlt ma dein ziel ?

 

so wida ein mittwoch...gleiches ziel.

 

ich hab x tabellen mit je einem primary key (autoincrement, weil oracle -> trigger)

jetzt soll ich in einem package die trigger zusammenfassen, dh ich mach mir ein package (stored procedure) und ruf das dann mit den einzelnen werten auf (old.id) zurück soll die neue id kommen (new.id), ich hab nur eine sequence erstellt, damit alle primary keys unique sind...

 

...nur irgentwie, naja ich les mir das manual nochamal durch :f:

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also zum einen lässt sich der Trigger "schöner" lösen... wozu eine Variable als "durchzug" verwenden?

 

das

SELECT trig.NEXTVAL INTO iAUTONUMBER FROM DUAL;

:new.IDBIKE := iAUTONUMBER;

 

funktioniert so

 

SELECT trig.NEXTVAL INTO :new.IDBIKE FROM DUAL;

 

genauso ;)

 

und ich versteh den sinn deiner sp noch immer nicht? wozu willst dir dafür eine sp bauen und soviel aufwand betreiben? den nextval bekommst doch mit nem einfachen select genauso?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich versteh nicht, warum du den trigger in ein package geben willst.. ein trigger ist ein skript, das führst du einmal aus, dann is der trigger in der datenbank und startet sich dann ja eh automatisch (sonst wärs ja kein trigger).

wieso schreibst einen trigger den du dann explizit aufrufst??? was macht das für einen sinn? oda versteh ich da was nicht?

Link zu diesem Kommentar
Auf anderen Seiten teilen

die sequence muss nicht in einem trigger sein, du hast dann halt pro tabelle eine sequence oder eine sequence für alle is doch egal.. (gibt halt dann lücken bei den pks), und in der procedure holst du dir mit nextaval den nächsten wert aus der sequence....
Link zu diesem Kommentar
Auf anderen Seiten teilen

die sequence muss nicht in einem trigger sein, du hast dann halt pro tabelle eine sequence oder eine sequence für alle is doch egal.. (gibt halt dann lücken bei den pks), und in der procedure holst du dir mit nextaval den nächsten wert aus der sequence....

 

ja das hab ich oben eh gesagt das mir eine squence reicht (dann sind alle keys unique), das prinzip davon hab ich eh verstanden, nur wie ichs lös nicht...

 

CREATE SEQUENCE S_TEST INCREMENT BY 1 START WITH 1;

 

so weit bin ich schon :f:

 

(ich hackl erst seit 4h mit oracle, und zaus hab ich keine möglichkeit was zu machen damit)

Link zu diesem Kommentar
Auf anderen Seiten teilen

wenn du diese sequence

CREATE SEQUENCE S_TEST INCREMENT BY 1 START WITH 1;

 

verwenden willst, dann einfach

 

IF INSERTING THEN

SELECT S_TEST.NEXTVAL INTO :new.IDBIKE FROM DUAL;

END IF;

 

aber den trigger musst trotzdem für jede table schreiben.

 

 

ich persönlich find das aber nicht sehr sauber weil du damit unnötig "löcher" in den ids hast. und die eine zeile mit der du für jeden table eine sequence erzeugst is net wirklich mehr arbeit und dann hast jede table mit ihren objekten getrennt und es gibt auch beim löschen / ändern keine probleme. Was nämlich bei einer sequence für alle tables dazu kommst ist, dass dann in nem jahr keiner mehr weiß, wo die überall verwendet wird und dann jemand anfängt zu löschen und plötzlich nix mehr geht. Hat jede table ihre eigenen objekte gibts das problem nicht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

naja du legst die sequence an, so wie du da geschrieben hast

ein bsp. von mir:

CREATE SEQUENCE SEQ_CAMPAIGN_ID

START WITH 1

MAXVALUE 999999999

MINVALUE 1

NOCYCLE

ORDER;

 

wichtg ist um die sequence zu benuetzen, auch das synonym und grant:

CREATE PUBLIC SYNONYM SEQ_CAMPAIGN_ID FOR SEQ_CAMPAIGN_ID;

 

GRANT ALTER, SELECT ON SEQ_CAMPAIGN_ID TO Public;

 

So jetzt hast du die sequence in der DB, wenn du jetzt irgendwo ein insert oder update machst, und somit auch den wert des pks änderst, welcher ja der wert aus der sequence sein soll, dann machst einfach nur:

Select seq_campaign_id into v_next_pk FROM DUAL

 

dann hast den nächsten wert aus der sequence, dieser ist aboslut eindeutig... weil das oracle ja selber regelt, du kannst das statement auch so ausführen im toad/sqlplus was auch immer du verwendest, du wirst immer den nächst höheren wert bekommen,

 

und wenn du dann das insert machst auf die tabelle, dann gibst du als wert einfach v_next_pk an.

Link zu diesem Kommentar
Auf anderen Seiten teilen

wenn du diese sequence

CREATE SEQUENCE S_TEST INCREMENT BY 1 START WITH 1;

 

verwenden willst, dann einfach

 

IF INSERTING THEN

SELECT S_TEST.NEXTVAL INTO :new.IDBIKE FROM DUAL;

END IF;

 

aber den trigger musst trotzdem für jede table schreiben.

 

ja soweit gehts jetzt schon

ich hab jetzt für jede tabelle einen trigger, und das läuft auf...

nur ich will nur einen trigger haben, den in eine sp auslagern und dann bei einem if inserting die sp aufrufen (als parameter die table und den spaltennamen übergeben), und dort dann die id setzen...weißt was ich mein?

 

lg

dominik

Link zu diesem Kommentar
Auf anderen Seiten teilen

ja soweit gehts jetzt schon

ich hab jetzt für jede tabelle einen trigger, und das läuft auf...

nur ich will nur einen trigger haben, den in eine sp auslagern und dann bei einem if inserting die sp aufrufen (als parameter die table und den spaltennamen übergeben), und dort dann die id setzen...weißt was ich mein?

 

lg

dominik

 

ein trigger ist an eine tabelle gekoppelt. meines wissens kann ein trigger nicht an mehrer tabellen gekoppelt werden. also müsstest du auch in der sp für jede table eine trigger anweisung schreiben. spart dir also nix an arbeit.

Link zu diesem Kommentar
Auf anderen Seiten teilen

versteh ichs immer noch nicht??? wozu überhaupt ein trigger???????? er kann sich doch einfach vor jedem insert den nächsten wert aus der sequence holen

 

klar könnte er ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ganz versteh ich immer noch nicht, welches Problem Du eigentlich lösen willst.

Sollte es nur darum gehen, unique PKs zu generieren (ohne dass die fortlaufend sein müssen) würde ich mir mal sys_guid() anschauen, damit kannst einen global unique identifier erzeugen, und die funktion kannst auch als default value für eine Spalte angeben:

 

create table t5(id$ raw(16) default sys_guid() constraint t5_pk primary key);

 

Quelle

 

Damit sparst Du Dir den ganzen Trigger

 

Die autonumber exception aus Deinem ursprünglichen trigger brauchst ja eigentlich auch nicht, da eine solche Änderung ja eh schon von den Primary / Foreign keys abgefangen werden sollte?

Link zu diesem Kommentar
Auf anderen Seiten teilen

ja schon, aber ich brauch ja einen trigger der das auslöst :confused:

 

ich machs jetzt amal so:

 

squence:

CREATE SEQUENCE S_TEST INCREMENT BY 1 START WITH 1;

 

 

trigger:

CREATE TRIGGER TRG_Bike
   BEFORE INSERT OR UPDATE ON Bike
   FOR EACH ROW
DECLARE
   iAUTONUMBER BIKE.IDBIKE%TYPE;
   cannot_change_AUTONUMBER EXCEPTION;
BEGIN
   IF INSERTING THEN
   SELECT trig.NEXTVAL INTO iAUTONUMBER FROM DUAL;
   :new.IDBIKE := iAUTONUMBER;
   END IF;

   IF UPDATING THEN
       IF NOT(:new.IDBIKE = :old.IDBIKE) THEN
           RAISE cannot_change_AUTONUMBER;
       END IF;
   END IF;
EXCEPTION
   WHEN cannot_change_AUTONUMBER THEN
   raise_application_error (-20000, 'AUTONUMBER KANN NICHT GEÄNDERT WERDEN');
END;

 

aus dem trigger nehm ich die Zeile raus:

SELECT trig.NEXTVAL INTO iAUTONUMBER FROM DUAL;

das kommt in eine ftk von einer procedure...

 

 

und jetzt muss ich noch den trigger in eine sp umbauen :confused:

 

das geht mich an, nedamal eine gscheite aufgabenstellung hamma, nix erklärt bekommen, und in 30mins muss es fertig sein :spinnst?:

Link zu diesem Kommentar
Auf anderen Seiten teilen

und was is "trig.NEXTVAL"?

 

wo hast du trig definiert und als was?

 

eventuell könnte man das mit variablen in der sp lösen in dem man einfach die table + spalten namen als variable übergibt. aber ich weiß nicht ob das auch in einer trigger-declaration funktioniert. ich schätze mal eher nicht.

 

dh du musst dann in deiner sp für jede table eine triggeranweisung schreiben und mittels in/out parameter table name und spaltenname übergeben und dann zu beginn mit if/else checken welche table du hast und den entsprechenden trigger in der sp aufrufen.

 

is aber weit mehr aufwand als für jede table einen trigger zu schreiben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

und was is "trig.NEXTVAL"?

 

wo hast du trig definiert und als was?

 

eventuell könnte man das mit variablen in der sp lösen in dem man einfach die table + spalten namen als variable übergibt. aber ich weiß nicht ob das auch in einer trigger-declaration funktioniert. ich schätze mal eher nicht.

 

dh du musst dann in deiner sp für jede table eine triggeranweisung schreiben und mittels in/out parameter table name und spaltenname übergeben und dann zu beginn mit if/else checken welche table du hast und den entsprechenden trigger in der sp aufrufen.

 

is aber weit mehr aufwand als für jede table einen trigger zu schreiben.

 

ja genau das will ich machen...

...ich glaub ich lass es :f:

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

 Teilen

×
×
  • Neu erstellen...