Announcement

Collapse
No announcement yet.

Cursor-Datentypen-Problem

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cursor-Datentypen-Problem

    Hallo,

    als letzte Aufgabe in Datenbanken II steht eine Aufgabe mit Prozeduren an.

    Man soll 2 Tabellen (Angestellte und Arbeiter) in eine Tabelle (Personal) zusammenführen. Weiter sollen Personaldaten, die dann in die Personal-Tabelle eingetragen werden, auch in den Angestellten- und Arbeiter-Tabellen auftauchen. Außerdem soll man eine Zuordnungstabelle führen, aus welchen Tabellen die Daten für die Personal-Tabelle stammen. Ursprünglich war mein Plan der, dass ich die Personal-ID zusammen mit einer Referenz auf einen Angestellten bzw einen Arbeiter in einer Zuordnungstabelle speichere. Irgendwie scheint sich die Referenz auf ein Objekt aber nicht so zu verhalten, wie z.B. in C++, jedenfalls hat das mit der Referenz überhaupt nicht funktioniert und SQL hat es geradezu herausgefordert, dass jetzt eben komplette Datensätze in der Zuordnungstabelle enden...

    Es gibt dazu zwei Prozeduren:

    Code:
    create or replace procedure linkePersonalMitArbeiter(personalnummer in number, arbeiter in u3_typ_arbeiter)
    is
    begin
    insert into u3_table_tabellenzuordnung values(personalnummer, null, arbeiter);
    end; create or replace procedure linkePersonalMitArbeiter(personalnummer in number, angestellter in u3_typ_angestellter) is begin
    insert into u3_table_tabellenzuordnung values(personalnummer, angestellter, null);
    end; a
    Zum Test habe ich dann einige Testtabellen erstellt (angestellter, personal und arbeiter) und einen Testdatensatz in personal und angestellter angelegt.

    dann habe ich versucht, die Prozeduren entsprechend zu testen:

    Code:
    declare
    cursor testangestellter (id_in in number) is select * from u3_testtable_angestellter where v_angstelltennummer = id_in; /*item testangestellter%ROWTYPE;*/ item u3_testtable_angestellter%ROWTYPE;
    begin
    open testangestellter(123); fetch testangestellter into item; dbms_output.put('itemname: '); dbms_output.put_line(item.v_name); linkepersonalmitangestellten(1, item); close testangestellter;
    end; a
    Das Problem ist, dass item kein typ von u3_typ_angestellter ist. Es liegt irgendwie an dem Datentyp, der aus dem Cursor kommt. testangestellter%rowtype ist jedenfalls auch nicht vom typ u3_typ_angestellter. Ich kann also im besten Fall das Objekt nach item fetchen und dann ausgeben lassen, jedoch kann ich das Item dann in keinem Fall an die Prozedur übergeben. Die Frage ist nun, wie caste ich den wie_auch_immer_er_lauten_mag-Typ, der aus dem Cursor kommt, in etwas brauchbares? Die gütligen Castmöglichkeiten in SQL würde ich nämlich auch mal als eher... naja, freundlich gesagt, überschaubar bezeichnen...

    schöne Grüße und Danke soweit

  • #2
    Was sind den u3_typ_arbeiter und u3_typ_angestellter für Typen?
    Ich kann mir kaum vorstellen, dass du als Anfänger gleich mit Oracle Object-Typen arbeitest - ich auch nicht nötig.

    Gruss

    Comment


    • #3
      Hallo,

      Danke für die Antwort,

      u3_typ_arbeiter und u3_typ_angestellter sind folgende typen:

      Code:
      create or replace type u3_typ_arbeiter as object
      (
      v_name varchar(180), v_vorname varchar(180), v_geburtsmonat varchar(180), v_stundenlohn number
      ); create or replace type u3_typ_angestellter as object (
      v_name varchar(180), v_geburtsdatum varchar(180), v_berufsbezeichnung varchar(180), v_monatsgehalt number, v_geschlecht varchar(16), v_angestelltennummer number
      ); create table u3_testtable_arbeiter of u3_typ_arbeiter; create table u3_testtable_angestellter of u3_typ_angestellter; a
      Naja, und ist Datenbanken II (über Sinn und Unsinn dieses Fachs für mein anschließendes Master-Vertiefungsfach lässt sich streiten, aber für den Bachelor braucht man eben 3 Vertiefungsfächer und das ist halt die Wahl zwischen Pest und Cholera, weil es grad mal 6 Fächer gibt und pro Semester auch nie alle angeboten werden) und Übung 2 waren Objekt-Typen, deren Erzeugung und Handhabung (lief auch ganz gut)... Übung 3 ist jetzt die "Spielerei" mit den Prozeduren und Ärger machen die Cursor und Datentypen von Rückgabewerten in SQL. Hab es einstweilen so gelöst, dass ich für jede Variable im Typ eine Variable in der Prozedur anlege, da die Variable des ausgewählten Datensatzes (welchen Variablentyp der auch immer haben mag) ablege und dann ein neues "Objekt" vom Typ u3_typ_angestellter in die Zuordnungstabelle schiebe. Hässlich, unschön, funktioniert einstweilen, SQL legts direkt auf sowas an aber wenn ich grad so meinen Schein bekomme, damit ich die letzte ausstehende Prüfung ablegen darf, bleibt das eben erst mal so

      aber wenn du eine elegantere (wobei wohl alles diesen Tatbestand aufweist) Lösung weist...

      schöne Grüße

      Comment


      • #4
        Zu meiner Zeit (vor ca. 15 Jahren) hiess "studieren" noch etwas anderes...
        Vergiss die Objekt-Typen in dieser Aufgabe und erzeuge Tabellen mit "normalen", d.h. skalaren Typen. Dann solltest du es hoffentlich hinbekommen.

        Noch ein paar Tipps/Fragen für die Praxis:
        • Bei Oracle sollte man immer VARCHAR2 anstatt VARCHAR nehmen.
        • Weshalb willst du das Geburtsdatum (v_geburtsdatum) als Zeichenkette abspeichern? Das gibt nur Ärger, nimm DATE oder einen der TIMESTAMP Typen.
        • Die gleiche Frage gilt auch für den Geburtsmonat (v_geburtsmonat), abgesehen davon dass ein keinen Monatsnamen gibt der 180 Zeichen lang ist. Dort gehört auch ein DATE, bzw. TIMESTAMP hinein. Wenn du wirklich nur den Monat hast, bzw. benötigst dann sollte es eine Zahl zwischen 1 und 12 sein aber kein Text!


        Gruss

        Comment


        • #5
          Ich vermute mal, Du meinst so etwas in der Richtung:
          Code:
          DECLARE
           l_angestellter u3_typ_angestellter;
          BEGIN
           SELECT VALUE(t) INTO l_angestellter FROM u3_testtable_angestellter t WHERE rownum=1; --Vereinfacht, ließt einfach immer die erste ermittelte Zeile
           DBMS_OUTPUT.PUT_LINE('Itemname '||l_angestellter.v_name);
          END;
          Beachte, dass das Argument für VALUE ein Tabellenalias, nicht der Tabellenname selbst sein muss.
          Dieser Link ist vielleicht noch hilfreich für dich: http://fara.cs.uni-potsdam.de/~uhlmann/19/ch10.html
          Zitat Tom Kyte:
          I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

          Comment


          • #6
            Hier ein kurzes Beispiel, wie es funktionieren könnte:
            Code:
            SET SERVEROUTPUT ON SIZE 900000;
            
            INSERT INTO u3_testtable_angestellter
               (     v_name, v_geburtsdatum,  v_berufsbezeichnung, v_monatsgehalt, v_geschlecht, v_angestelltennummer)
              VALUES 
              ('Mustermann',   '01.01.1980', 'Musterangestellter',           3000,  'maennlich',                  123); 
            
            
            DECLARE
              CURSOR testangestellter (id_in IN NUMBER) IS
                --SELECT u3_typ_angestellter( v_name, v_geburtsdatum,  v_berufsbezeichnung, v_monatsgehalt, v_geschlecht, v_angestelltennummer)
                SELECT VALUE(t)
                  FROM u3_testtable_angestellter t
                 WHERE v_angestelltennummer = id_in;
            
              item  u3_typ_angestellter;
              
            BEGIN
              OPEN testangestellter (123);
            
              FETCH testangestellter INTO item;
            
              DBMS_OUTPUT.put_line ('itemname: '||item.v_name);
            
              linkePersonalMitAngestellten(1, item);
              
              CLOSE testangestellter;
            END;
            
            1 row created.
            itemname: Mustermann
            Ich habe gleich mal die Verbesserung von @dimitri eingebaut ;-)

            Comment

            Working...
            X