Announcement

Collapse
No announcement yet.

Nach einem Teilinhalt suchen

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

  • Nach einem Teilinhalt suchen

    Hallo Zusammen,

    für ein Delphi-Programm mit einer Oracle-Datenbank muß ich einen Trigger programmieren.

    Leider habe ich nur geringe PL/SQL-Kenntnisse und benötige daher Eure Hilfe.

    Ich habe in den Stammdaten eine Übersetzungstabelle mit zwei VARCHAR2-Feldern: IST und SOLL. In einer Tabelle mit den Bewegungsdaten soll jetzt für ein VARCHAR2-Feld überprüft werden, ob ein Teil des Inhaltes einem Eintrag in der Spalte IST der Übersetzungstabelle entspricht. Wenn ja, so soll das ganze Feld der Bewegungstabelle mit dem Eintrag SOLL ersetzt werden. Ansonsten soll der Eintrag unverändert übernommen werden.

    Beispiel:
    In der Übersetzungstabelle 'BETREUER' steht u.a. folgender Eintrag: IST = 'Mayer', SOLL = 'Mayer, Andreas'.
    Wenn der Anwender jetzt in dem Feld BETREUER der Tabelle KUNDEN irgendeinen Text eingibt, der 'Mayer' enthält (z.B. 'Mayer', 'A.Mayer' oder 'Mayer, A.'), so soll dieser durch 'Mayer, Andreas' ersetzt werden.

    Kann und würde mir einer von Euch helfen?

    Gruß
    Thomas

  • #2
    http://www.techonthenet.com/sql/like.php
    Christian

    Comment


    • #3
      Originally posted by tpcol View Post
      ...Kann und würde mir einer von Euch helfen?
      Ja, sicher...
      Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

      Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

      Comment


      • #4
        Beim Filtern könnten auch reguläre Ausdrücke helfen, aber es wird schwer zu entscheiden ob wo bei "Andreas Mayer" Vorname und Nachname steht:

        Code:
        WITH data AS
         (SELECT 'Mayer'    t_ist  FROM dual UNION ALL
         SELECT  'A.Mayer'         FROM dual UNION ALL
         SELECT  'Andreas Mayer'   FROM dual UNION ALL
         SELECT  'Mayer,Andreas'   FROM dual UNION ALL
         SELECT  'Mayer, Andreas'  FROM dual UNION ALL
         SELECT  'Mayer, Andreas'  FROM dual UNION ALL
         SELECT  'Mayer, A.'       FROM dual)
        SELECT regexp_replace(t_ist,'(.[\.\,])*?([a-Z]{5,})(.*)','\2') str 
        FROM data;
        
        str
        ----------------
        Mayer
        Mayer
        Andreas
        Mayer
        Mayer
        Mayer
        Mayer

        Comment


        • #5
          Diese Ersetzung soll ohne Benutzerinteraktion im Trigger stattfinden? Erstaunlich!
          Es riecht auch ein wenig nach künstlicher Intelligenz.
          Was passiert wenn es mehrere Treffer gibt?

          Ich würde beginnen, indem ich zunächst eine Funktion schreibe, ungefähr namens "höchste Ähnlichkeit" oder so.
          Die Funktion muss in der Lage sein, den Eingangsparameter (die spätere Nutzereingabe) in (Namens-)Teile zu zerlegen.
          Diese Teile vergleicht sie mit den Istwerten und spuckt den besten Treffer aus.

          Das ganze kannst Du bequem in einem Select Statement testen und notfalls auch in einen Trigger einbauen.
          Oder die Funktionsergebnisse dem Anwender zur Auswahl anzeigen.
          Gruß, defo

          Comment


          • #6
            Hallo,

            sowas sollte, wenn ich dich richtig verstanden habe, soweit klappen, so lange die Namen Eindeutigkeit erlangen können. Ansonsten halt im Client die Möglichkeit zur Wahl lassen

            [highlight=sql]
            with data as
            (select 1 id,'Mayer' T_IST,'Andreas Meyer' T_SOLL from DUAL union all
            select 2 id, 'Müller','Klaus Müller' from DUAL union all
            select 3 id,'schulzr' ,'Klaus schulzr' from DUAL union all
            select 4 id,'Meier A.','Andreas Meier' from DUAL)
            select B.T_SOll,upper(REGEXP_REPLACE(a.T_IST,'(.[\.\,])*?([a-Z]{5,})(.*)','\2')),UPPER(REGEXP_REPLACE('&name2','( .[\.\,])*?([a-Z]{5,})(.*)','\2'))
            from data a
            join data B
            on a.id=B.id
            where UPPER(REGEXP_REPLACE(a.T_IST,'(.[\.\,])*?([a-Z]{5,})(.*)','\2')) like UPPER(REGEXP_REPLACE('&name2','(.[\.\,])*?([a-Z]{5,})(.*)','\2'));

            DEFINE name= müller, k.
            DEFINE NAme2=%.&name
            [/highlight]

            Comment


            • #7
              Hallo Zusammen,

              so wie ich Eure Vorschläge sehe, habe ich mich vermutlich nicht präzise genug ausgedrückt. Insbesondere habe ich vergessen zu schreiben, daß die zu ersetzenden Einträge eindeutig sind. Sollte es wirklich vorkommen, daß der Anwender versehentlich Begriffe in das eine Feld schreibt, der mehrere Treffer liefert, so soll einer der Treffer genommen werden; egal welcher - so zumindestens die Absprache mit den Anwendern. Ein weiterer Grund für den Trigger ist, daß wir die Daten der letzten 10 Jahre aus diversen, gleichformatierten Excel-Tabellen übernehmen wollen (ca. 150.000 Datensätze). Und dort ist in der zu prüfenden Spalte die Angabe in allen erdenklichen Varianten zu finden. Die eindeutige Zeichenfolge ist glücklicherweise immer enthalten.

              Des Weiteren sehe ich in Euren Codes immer die Namen als statischen Text und nicht als Variable Tabelleneinträge.

              Ich habe heute früh folgende Varainte ausprobiert:

              Code:
              DECLARE
                p PERSONEN%ROWTYPE;
              BEGIN
                FOR p IN 
                  (SELECT * FROM PERSONEN) 
                Loop
                  IF INSTR(UPPER(:new.PERSON), UPPER(p.IST)) > 0 THEN
                    :new.PERSON := p.SOLL;
                    EXIT FOR;
                  END IF;
                END LOOP;
              END;
              Ich hoffe nur, daß es etwas eleganter (schneller) geht, als mit dieser Schleife. Aktuell haben wir nur ca. 20 Einträge, aber wenn es mehr werden ...

              Gruß aus Köln
              Thomas
              Zuletzt editiert von tpcol; 27.07.2012, 21:28.

              Comment


              • #8
                Hallo Thomas

                Kein einziges Code Beispiel in diesem Thread ist ein Trigger, wir haben dir nur das Prinzip mit dem Vergleich vorgeschlagen.
                Die statischen Namen durch eine Variable zu ersetzen sollte doch wohl kein Problem sein für einen Entwickler.

                Dein Code funktioniert so nicht, zumindest nicht bei einen "FOR EACH ROW" Trigger. Du kannst die Tabellle Personen nicht im Trigger selektieren.

                Gruss

                Comment


                • #9
                  Hallo Zusammen,

                  dann werde ich mir den Befehl REGEXP_REPLACE mal näher ansehen.

                  @Wernfried: mein Code funktioniert in dem "FOR EACH ROW"-Trigger für INSERT und UPDATE fehlerfrei. Somit hat sich Deine Prognose, daß er nicht funktionieren würde, glücklicherweise nicht bewahrheitet.

                  Gruß aus Köln
                  Thomas

                  Comment


                  • #10
                    Hallo Thomas

                    Ich bin davon ausgegagen, dass dein Trigger für die Tabelle Personen gilt. Nachdem ich mir deinen ersten Beitrag noch einmal genauer angesehen habe sieht die Sache anders aus.

                    Es ist sonst nicht meine Art aber da ich dich verwirrt habe, hier ein vollständiges Beispiel welches deine Bedürfnisse abdecken sollte.

                    [highlight=SQL]
                    CREATE OR REPLACE TRIGGER BUI_KUNDEN
                    BEFORE INSERT OR UPDATE ON KUNDEN
                    FOR EACH ROW
                    BEGIN
                    SELECT NVL(MIN(SOLL), :NEW.PERSON)
                    INTO :NEW.PERSON
                    FROM BETREUER
                    WHERE REGEXP_LIKE(:NEW.PERSON, IST, 'i');
                    END;
                    [/highlight]

                    Das "NVL" sorgt dafür, dass der orginal Text verwendet wird wenn nichts gefunden werden sollte.
                    Das 'i' weisst Oracle an, Gross- und Kleinschreibung zu ignorieren.

                    Gruss

                    Comment


                    • #11
                      Hallo Wernfried,

                      vielen Dank für den Befehl. Da wäre ich, mangels Oracle-Kenntnisse, nie drauf gekommen.

                      Gruß
                      Thomas

                      Comment

                      Working...
                      X