PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Logikfehler der PHP/MySQL-INSERT-Funktion

Die Fehler:

  • RETURNING Klausel fehlt im zweiten INSERT Aussage.

  • Geben Sie eine explizite Liste von Spalten für Ihr zweites INSERT an Aussage auch.

  • Geben Sie nicht NULL an im INSERT Aussagen wenn Sie möchten, dass der Spaltenstandard (serielle Spalten?) aktiviert wird. Verwenden Sie das Schlüsselwort DEFAULT oder erwähne die Spalte einfach gar nicht.

Die bessere Lösung:

Verwenden Sie Datenveränderungs-CTE , verfügbar seit PostgreSQL 9.1, um alles in einer Anweisung zu erledigen und Overhead und Roundtrips zum Server zu sparen. (MySQL kennt nichts dergleichen, nicht einmal einfache CTEs).

Überspringen Sie auch das UPDATE durch Neumodellierung der Logik. Rufen Sie eine ID mit nextval() ab , und kommen Sie mit nur zwei INSERT aus Aussagen.

Unter der Annahme dieses Datenmodells (das hätten Sie in Ihrer Frage angeben sollen):

CREATE TABLE institutions(i_id serial, name text, u_id int);
CREATE TABLE staff(user_id serial, username text, password text, i_id int);

Diese eine Abfrage macht alles:

WITH x AS (
    INSERT INTO staff(username, password, i_id) -- provide column list
    VALUES ('$username', '$password', nextval('institutions_i_id_seq'))
    RETURNING user_id, i_id
    )
INSERT INTO institutions (i_id, u_id, name)
SELECT x.i_id, x.user_id, '$institution'
FROM   x
RETURNING u_id, i_id; -- if you need the values back, else you are done

Datenmodell

Sie könnten darüber nachdenken, Ihr Datenmodell auf eine klassische n:m-Beziehung umzustellen. Würde diese Tabellen und Primärschlüssel enthalten:

staff (u_id serial PRIMARY KEY, ...)
institution (i_id serial PRIMARY KEY, ...)
institution_staff (i_id, u_id, ...,  PRIMARY KEY(i_id, u_id)) -- implements n:m

Sie können institution_staff.i_id UNIQUE immer definieren , wenn ein Benutzer nur einer institution angehören kann .