Primärschlüssel automatisch vergeben

Hallo,

ich bin neu hier und habe direkt eine Frage:
Ich wollte eine Tabelle mit einem automatisch zu vergebenden Primärschlüssel anlegen. Dies hat mit SERIAL auch so weit geklappt. Damit ich nun Werte per INSERT eingeben kann muss ich aber nun angeben, welcher Wert wohin kommt, siehe hier:

Insert into User (firstname,la…) Values (…

also firstname, lastname usw. Wenn ich es einfach mit INSERT into User VALUES versuche, gibt es dann einen Fehler, da an erster Stelle ein Integer Wert erwartet wird.

Ich entwickle derzeit ein Programm, dass u.a. automatisch Benutzer (User) anlegen soll. Dabei sind nicht alle Felder in der Tabelle Pflichtfelder. Nun bräuchte ich ja nach diesem Schema jedes mal einen anders aufgebauten SQL Befehl (z.b. ohne firstname, mit firstname usw.).

Muss ich nun alle möglichen Kombinationen an SQL Befehlen anlegen, oder gibt es hier auch eine bessere Variante?

Vielen Dank!!

Hallo!

Serial legt eine Sequence an, da kannt du über nextval den jeweils nächsten Wert auslesen und in die DB eintragen.
Ansonsten kann ich dir ein Framework oder ORM ans Herz legen, das dir im Code sowas abnimmt. Wie gut das funktioniert kommt natürlich auch drauf an, womit du entwickelst.

Gruß Uwe

Du setzt für die Spalte im INSERT einfach DEFAULT ein, oder aber läßt diese Spalte weg. Also, Spalte z.B. id, welche Dein PK ist und vom Typ SERIAL und die erste Spalte ist:

insert into table (id, vorname, name) values (default, 'max','mustermann');
insert into table (name, vorname) values ('max'm'mustermann');

In beiden Fällen wird in der Spalte id der nächste Wert von SERIAL stehen. Willst Du diesen nach dem Insert noch verwenden, kannst Du RETURNING id noch angeben. Willst Du diese id dann noch z.B. in in weiteren INSERTS verwenden, kannst Du (achtung, neu seit 9…1) wCTE verwenden:

test=# create table person(id serial primary key, vorname text, nachname text);NOTICE:  CREATE TABLE will create implicit sequence "person_id_seq" for serial column "person.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "person_pkey" for table "person"
CREATE TABLE
Time: 5,350 ms
test=*# create table telefon (id serial primary key, person_id int references person, notiz text, nummer text);NOTICE:  CREATE TABLE will create implicit sequence "telefon_id_seq" for serial column "telefon.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "telefon_pkey" for table "telefon"
CREATE TABLE
Time: 4,981 ms
test=*# with id_person as (insert into person (vorname, nachname) values ('max','musermann') returning id), id_telefon as (insert into telefon values (default, (select id from id_person), 'Privathandy','4711-0815') returning id) select id_person.id as person, id_telefon.id as telefon from id_person cross join id_telefon;
 person | telefon
--------+---------
      1 |       1
(1 row)

oder auch:

test=# with
test-#   id_person as (
test(#     insert into person (vorname, nachname) values ('max2','mustermann2') returning id
test(#   ),
test-#   id_telefon as (
test(#     insert into telefon (person_id, notiz, nummer)
test(#       select * from (select id from id_person) foo cross join
test(#       (select 'Privathandy' || s::text,'4711-0815' || s::text from generate_series(1,5) s) bar
test(#       returning id
test(#
test(#   )
test-#   select id_person.id as person, id_telefon.id as telefon from id_person cross join id_telefon;
 person | telefon
--------+---------
      2 |       2
      2 |       3
      2 |       4
      2 |       5
      2 |       6
(5 rows)

Für Deine Formularverarbeitung: prüfe vor dem Eintrag, was Du einträgst. Es gibt passende Funktionen, in PHP z.B. pg_escape_string oder so, die nehmen da viel Arbeit ab.