Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Duplicate key update

  1. #1
    gdietrich ist offline Neuer Benutzer
    Registriert seit
    04.01.2012
    Beiträge
    27

    Standard Duplicate key update

    Unter Mysql funktioniert ja dieser Befehl, under PG nicht:

    INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; UPDATE table SET c=c+1 WHERE a=1;
    Ich hab mir daher eine Funktion geschrieben die 5 Werte erhält ( var1 - var5 )
    Die insert Funktion läuft wie sie soll, nur der Update geht schief !
    Spaltenverweis »e« ist nicht eindeutig at character 65DETAIL: Er könnte sich entweder auf eine PL/pgSQL-Variable oder eine Tabellenspalte beziehen.

    Die Funktion:

    LOOP

    UPDATE table SET "e" = (var5) WHERE "a" = (var1) AND "b" = (var2);
    IF found THEN RETURN;
    END IF;
    BEGIN
    INSERT INTO table (a, b, c, d, e)
    VALUES ((var1), (var2), (var3), (var4), (var5));
    RETURN;
    EXCEPTION WHEN unique_violation THEN
    END;
    END LOOP;

    Ich hab seither nichts gefunden, was mir da irgendwie weiterhilft. Es muss doch möglich sein auch im Update die variablen zu benutzen.
    Vermute mal mir fehlen irgendwo wieder () oder ' , hab alle Kombinationen irgendwie auch schon probiert aber seh wohl geade den einen Baum nicht !!

  2. #2
    castorp ist offline Erfahrener Benutzer
    Registriert seit
    27.06.2009
    Beiträge
    525

    Standard

    Wenn Du 9.1 verwendest, geht das auch mit einem einzigen SQL Statement:

    Code:
    WITH new_values (a,b,c,d,e) as (
      values 
         (1, 2, 3, 4, 5)
    
    ),
    upsert as
    ( 
        UPDATE mytable m 
            set m.e = nv.e
        FROM new_values nv
        WHERE m.a = nv.a
          AND m.b = nv.b
        RETURNING m.*
    )
    INSERT INTO mytable (a,b,c,d,e)
    SELECT a,b,c,d,e
    FROM new_values
    WHERE NOT EXISTS (SELECT 1 
                      FROM upsert up 
                      WHERE up.a = new_values.a
                        AND up.b = new_values.b)
    Wenn Du mehr als einen Datensatz ändern/einfügen willst, dann häng die weiteren Werte einfach in den "VALUES" Teil:

    Code:
    WITH new_values (a,b,c,d,e) as (
      values 
         (1, 2, 3, 4, 5),
         (10,20,30,40,50),
         (100,200,300,400,500)
    ),
    ....
    A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

  3. #3
    gdietrich ist offline Neuer Benutzer
    Registriert seit
    04.01.2012
    Beiträge
    27

    Standard

    Nein da wird immer ein Datensatz geändert bzw, eingefügt.
    Die Funktion bekommt 5 Werte übermittelt, wenn der Datensatz existiert WHERE "a" = (var1) AND "b" = (var2) soll nur das Feld e aktualisiert werden ( Zeitstempel aus der Applikation ) ( var1 und var2 sind ein zusammengesetzter Primärschlüssel ).

    Werd mal die Funktion umschreiben und testen.

    Danke !

  4. #4
    castorp ist offline Erfahrener Benutzer
    Registriert seit
    27.06.2009
    Beiträge
    525

    Standard

    Zitat Zitat von gdietrich Beitrag anzeigen
    Nein da wird immer ein Datensatz geändert bzw, eingefügt.
    Die Funktion bekommt 5 Werte übermittelt, wenn der Datensatz existiert WHERE "a" = (var1) AND "b" = (var2) soll nur das Feld e aktualisiert werden ( Zeitstempel aus der Applikation ) ( var1 und var2 sind ein zusammengesetzter Primärschlüssel ).
    Das ist exakt was mein Statement macht.

    Mit festen Werten für einen Datensatz kann man das auch etwas einfacher schreiben:
    Code:
    WITH upsert as
    ( 
        UPDATE mytable m 
            set m.e = 5
        FROM new_values nv
        WHERE m.a = 1
          AND m.b = 2
        RETURNING m.*
    )
    INSERT INTO mytable (a,b,c,d,e)
    SELECT 1,2,3,4,5
    FROM new_values
    WHERE NOT EXISTS (SELECT 1 FROM upsert up)


    Zitat Zitat von gdietrich Beitrag anzeigen
    Ich hab seither nichts gefunden, was mir da irgendwie weiterhilft. Es muss doch möglich sein auch im Update die variablen zu benutzen.
    Du müsstest schon die gesamte Funktion hier posten, ich werde aus dem Beispiel nicht schlau

    Und bitte pack um Dein SQL [code] Tags, damit das lesbar wird. Näheres dazu hier: http://www.pg-forum.de/misc.php?do=bbcode
    Geändert von castorp (06.01.2012 um 22:30 Uhr)
    A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

  5. #5
    gdietrich ist offline Neuer Benutzer
    Registriert seit
    04.01.2012
    Beiträge
    27

    Standard

    CREATE OR REPLACE FUNCTION safetytr.func_masterdata
    (
    IN line integer,
    IN shift integer,
    IN points integer,
    IN firstinput timestamp WITHOUT TIME ZONE,
    IN actualtime timestamp WITHOUT TIME ZONE
    )
    RETURNS SETOF integer AS
    $$
    begin
    [ident] WITH new_values (var1, var2, var3, var4, var5)
    as (
    VALUES (line,shift,points,firstinput,actualtime)
    ),
    upsert as
    (
    UPDATE safetytr.triggerinputmaster m
    SET m.var5 = nv.var5
    FROM new_values nv
    WHERE m.var1 =nv.var1
    AND m.var2 = nv.var2
    RETURNING m.*
    )
    INSERT INTO safetytr.triggerinputmaster (var1, var2, var3, var4, var5)
    SELECT var1, var2, var3, var4, var5
    FROM new_values
    WHERE NOT EXISTS (SELECT 1
    FROM upsert up
    WHERE up.var1 =new_values.var1
    AND up.var2 = new_values.var2)

    end
    $$


    So sieht das gerade aus, hoffe das ist verständlicher.

  6. #6
    castorp ist offline Erfahrener Benutzer
    Registriert seit
    27.06.2009
    Beiträge
    525

    Standard

    Mit welcher Sprache ist das? SQL oder PLpgSQL?

    Denn mit einer SQL Funktion kannst Du nur über Positionen ($1, $2 usw) auf die Parameter zugreifen. Mit PLpgSQL könntest Du auch via Namen zugreifen

    Mein vereinfachtes Beispiel war übrigens falsch, aber ich kann den Beitrag nicht mehr editieren:
    Code:
    WITH upsert as
    ( 
        UPDATE mytable m 
            set m.e = 5
        WHERE m.a = 1
          AND m.b = 2
        RETURNING m.*
    )
    INSERT INTO mytable (a,b,c,d,e)
    SELECT 1,2,3,4,5
    FROM new_values
    WHERE NOT EXISTS (SELECT 1 FROM upsert up)
    (Da war noch ein FROM new_values drin, was da nicht hingehört)
    Geändert von castorp (06.01.2012 um 23:31 Uhr)
    A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

  7. #7
    gdietrich ist offline Neuer Benutzer
    Registriert seit
    04.01.2012
    Beiträge
    27

    Standard

    Hab ich wohl die wichtigste Zeile meiner Funktion vergessen.
    LANGUAGE 'plpgsql'

  8. #8
    gdietrich ist offline Neuer Benutzer
    Registriert seit
    04.01.2012
    Beiträge
    27

    Standard

    Kann mir vielleicht trotzdem jemand noch sagen warum in meiner ersten Frage ein INSERT funktioniert aber kein UPDATE ?
    Man will ja nicht dumm sterben !!

  9. #9
    gdietrich ist offline Neuer Benutzer
    Registriert seit
    04.01.2012
    Beiträge
    27

    Standard

    ok, hab das jetzt mal anders probiert:
    statt
    UPDATE table SET "e" = (var5) WHERE "a" = (var1) AND "b" = (var2);
    hab ich
    UPDATE table SET "e" = now() WHERE "a" = (var1) AND "b" = (var2);
    und dann läüft es, hatte da wohl einen kleinen Denkfehler drin.

  10. #10
    castorp ist offline Erfahrener Benutzer
    Registriert seit
    27.06.2009
    Beiträge
    525

    Standard

    Zitat Zitat von gdietrich Beitrag anzeigen
    ok, hab das jetzt mal anders probiert:
    statt
    UPDATE table SET "e" = (var5) WHERE "a" = (var1) AND "b" = (var2);
    hab ich
    UPDATE table SET "e" = now() WHERE "a" = (var1) AND "b" = (var2);
    und dann läüft es, hatte da wohl einen kleinen Denkfehler drin.
    Kleine Anmerkung: sowohl die Klammern um die Variablen als auch die Anführungszeichen sind überflüssig.

    Warum das Orginal nicht funktioniert kann ich nicht sagen (da fehlt die halbe Funktione)

    Mein Statement war eigentlich als komplette Ersatz für die Funktion gedacht. Deine ursprüngliche Idee war ja ein "update or insert" in einen Aufruf (= 1 Statement) zu verpacken. Mit dem "writeable CTE" kannst Du das direkt als ein Statement laufen lassen, ohne eine Funktion erstellen zu müssen.


    Die Fehlermeldung klingt aber danach als hättest Du eine Variable mit dem Namen e und eine Spalte mit dem Namen e.

    Und zum Schluss nochmal die Bitte SQL Statements in [code] Tags einzuschliessen (so wie ich es gemacht habe)
    Die Erläuterungen dazu sind hier: http://www.pg-forum.de/misc.php?do=bbcode
    (Ausserdem auf jeder Seite unten Rechts unter dem Titel "BB-Code ist an")
    A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Problem ERROR: duplicate key value violates unique constraint
    Von Hannes23 im Forum Allgemeines
    Antworten: 4
    Letzter Beitrag: 15.12.2011, 14:43
  2. Insert, Update Trigger der Update ausführt
    Von Tentoxa im Forum Trigger und Funktionen
    Antworten: 2
    Letzter Beitrag: 21.06.2010, 11:31
  3. Inserets duplicate
    Von ThoHei im Forum SQL
    Antworten: 6
    Letzter Beitrag: 19.02.2010, 14:08
  4. Aufruf von Update vor einem Update auf gleiche Tabelle
    Von Heisp im Forum Trigger und Funktionen
    Antworten: 3
    Letzter Beitrag: 26.06.2007, 14:21
  5. on duplicate key
    Von Steve9825679 im Forum SQL
    Antworten: 2
    Letzter Beitrag: 29.05.2007, 16:29

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum