Ankündigung

Einklappen
Keine Ankündigung bisher.

ON DUPLICATE KEY UPDATE mit PostgreSQL

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • ON DUPLICATE KEY UPDATE mit PostgreSQL

    Moin,

    ich versuche gerade meinen QueryBuilder auf PostgreSQL zu erweitern. Was ist der cleverste weg, das von MySQL bekannte ON DUPLICATE KEY UPDATE mit PostgreSQL zu realisieren?

    Ein Beispiel:
    PHP-Code:
    INSERT INTO
        table
        
    (idabcdefghij)
        
    SELECT
            id
    abcdefghij
        FROM
            sometable st
    ON DUPLICATE KEY UPDATE
        id 
    LAST_INSERT_ID(id),
        
    VALUES(a),
        
    NOW(),
        
    1,
        
    CONCAT(e'-'f); 
    Was soll das?

    Ein so formuliertes Insert aktualisiert einen Datensatz, wenn dieser bereits existiert. "Existiert" heisst, wenn ein Primary-Key oder ein Unique-Key verhindern, dass die übergebenen Daten ein Insert auslösen. In dem Fall wird dann automatisch ein Update gefahren. Der Trick "id = LAST_INSERT_ID(id)," macht, dass ich nach einem Insert ODER nach einem Update immer auf die last-insert-id zugreifen kann. "a = VALUES(a)" heisst "nimm den übergebenen Wert".

    Das oben aufgeführte Beispiel zeigt ein Massinsert. Hier wird vielleicht auffallen, dass das "id = LAST_INSERT_ID(id)" unsinnig ist. Richtig - das macht nur Sinn, wenn ich einzelne Datensätze einfüge.

    Warum das alles überhaupt? Warum nicht einfach zu Fuß?
    Weil dieses Statement tatsächlich viele Aufgaben übernimmt, für die man sonst mindestens 3 Queries bräuchte. Ich weiss beispielsweise nicht automatisch, was der Autoincrement-Schlüssel (der in anderen Datenbanken ggf anders heisst) ist.

    Jedenfalls kann ich so mit sehr einfachen Mitteln ein Insertstatement erstellen:

    PHP-Code:
    $_POST = array(
        
    'field1' => 123,
        
    'field2' => '" SELECT 1 FROM',
        
    'field3' => 'NOW()',
        
    'field4' => 12345
    );

    $id $builder->insert()
    ->
    into('table')
    ->
    setArray($_POST, ['field1''field2''field3'/* mask */)
    ->
    setInsertOrUpdate('field4'456)
    ->
    setUpdateRaw('last_update=NOW()')
    ->
    exec(); 
    (Wie) kann ich das obrige SQL-Beispiel mit ähnlichen Komfort auf PostgreSQL portieren?

  • #2
    Mit einem Merge Statment, komfortable ist aber was anderes.

    Kommentar


    • #3
      Zitat von rkr Beitrag anzeigen
      Moin,

      ich versuche gerade meinen QueryBuilder auf PostgreSQL zu erweitern. Was ist der cleverste weg, das von MySQL bekannte ON DUPLICATE KEY UPDATE mit PostgreSQL zu realisieren?
      Es gibt in PG keine direkt nutzbare Funktion dieser Nicht-Standard.SQL - Funktion, aber eine Menge Lösungsansätze. Google bitte nach "postgresql upsert cte" oder so. Ich denke mal, 9.5 wird da was bringen, da basteln einige dran, scheitern aber bisher an der 'Firewall' Tom "tgl" Lane.
      PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

      Kommentar


      • #4
        Dass es eine Nicht-Standard-SQL-Funktion ist, ist mir durchaus bewusst.
        UPSERT ist ein gutes Stichwort: http://www.the-art-of-web.com/sql/upsert/

        Kommentar


        • #5
          Zitat von rkr Beitrag anzeigen
          Dass es eine Nicht-Standard-SQL-Funktion ist, ist mir durchaus bewusst.
          Wie gesagt. Um es bildlich auszudrücken: http://imageshack.us/a/img199/1284/b9w.jpg
          Aber Tom ist echt ein Guru, und er hat nachvollziehbare Gründe, wenn er was ablehnt. Aber ich bin mir relativ sicher, daß es in 9.5 sein wird. Aktuelle Meldung von heute:

          Tom Lane

          5:36 AM (3 hours ago)

          to pgsql-committers
          Stamp HEAD as 9.5devel.



          Schau Dir an, was Google liefert. Zum Beispiel http://jakub.fedyczak.net/post/merge...sql-using-cte/ , aber es gibt noch andere Lösungen.
          PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

          Kommentar


          • #6
            Kein MERGE in Postgres? Wie konnte das denn passieren? Das eigentliche Problem bleibt aber das selbe, der PK muss zwingend bekannt sein.

            Kommentar


            • #7
              Zitat von erc Beitrag anzeigen
              Kein MERGE in Postgres? Wie konnte das denn passieren? Das eigentliche Problem bleibt aber das selbe, der PK muss zwingend bekannt sein.
              Und evtl. vorhandene Unique-Keys (abhängig vom Lösungskonzept) ebenfalls.

              Kommentar


              • #8
                Zitat von erc Beitrag anzeigen
                Kein MERGE in Postgres? Wie konnte das denn passieren?
                Weil es a) nicht im Standard ist und b) die bisherigen Implementierungen bzw. Patches dafür nicht perfekt waren. Es ist schwerer, etwas zu korrigieren, als etwas, was halbgar ist, abzuweisen. In PG werden Dinge erst dann gemacht, wenn sie *wirklich* und *sicher* und *stabil* funktionieren. Man stellt lieber Features zurück, um vielleicht eine bessere Implementierung zu finden, als Dinge aufzunehmen, wenn man da noch Bauchschmerzen hat. Das Thema Upsert z.B. zieht sich schon a paar Jahre durch diverse Mailinglisten.
                PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                Kommentar


                • #9
                  Zitat von akretschmer Beitrag anzeigen
                  In PG werden Dinge erst dann gemacht, wenn sie *wirklich* und *sicher* und *stabil* funktionieren. Man stellt lieber Features zurück, um vielleicht eine bessere Implementierung zu finden, als Dinge aufzunehmen, wenn man da noch Bauchschmerzen hat. Das Thema Upsert z.B. zieht sich schon a paar Jahre durch diverse Mailinglisten.
                  Grundsätzlich würde ich so eine Aussage immer verteidigen! Aber PostgreSQL ist kein Browser. PostgreSQL ist nicht in der Pflicht nicht mehr anzubieten, als der Standard es hergibt. Die Behauptung, dass man sein SQL so halten sollte, dass man eine beliebige Datenbank nutzen könnte, funktioniert in der Praxis ohnehin nicht (abgesehen von DBAL, klar soweit). Und das wird auch nicht mehr kommen. Daher fehlt mir an dieser Stelle etwas das Verständnis für diese Standardverliebtheit.

                  Kommentar


                  • #10
                    Zitat von rkr Beitrag anzeigen
                    Grundsätzlich würde ich so eine Aussage immer verteidigen! Aber PostgreSQL ist kein Browser. PostgreSQL ist nicht in der Pflicht nicht mehr anzubieten, als der Standard es hergibt. Die Behauptung, dass man sein SQL so halten sollte, dass man eine beliebige Datenbank nutzen könnte, funktioniert in der Praxis ohnehin nicht (abgesehen von DBAL, klar soweit). Und das wird auch nicht mehr kommen. Daher fehlt mir an dieser Stelle etwas das Verständnis für diese Standardverliebtheit.
                    Es geht nicht um Standardverliebtheit. DISTINCT ON() ist auch kein Standard, selbst Indexe kennt der Standard nicht. Oder HSTORE und JSON als Datentyp. Das Problem mit MERGE bzw. UPSERT war bisher, daß es keiner sauber implementiert hat. That's all.
                    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                    Kommentar


                    • #11
                      Zitat von akretschmer Beitrag anzeigen
                      Es geht nicht um Standardverliebtheit. DISTINCT ON() ist auch kein Standard, selbst Indexe kennt der Standard nicht. Oder HSTORE und JSON als Datentyp. Das Problem mit MERGE bzw. UPSERT war bisher, daß es keiner sauber implementiert hat. That's all.
                      Was ist an der Lösung von MySQL unsauber? (not to intend to offend)
                      Die JSON-Funktionen von PostgreSQL sehen sehr lecker aus.

                      Kommentar


                      • #12
                        Zitat von rkr Beitrag anzeigen
                        Was ist an der Lösung von MySQL unsauber?
                        Ich meinte damit die Realisierung in PG bzw. bisherige Lösungsansätze. Ich hab jetzt keine Lust, die Diskussion auf den Mailinglisten dazu rauszukramen.
                        PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                        Kommentar

                        Lädt...
                        X