PostgreSQL serial of OID
Ik ben een online boek over PostgreSQL aan het doornemen. Ik stuit echter op een vraag waarvan ik het antwoord daar niet kan vinden:
In MySQL gebruikte ik altijd een integerveld met de naam ID waar ik een Primary Key en een AUTO_INCREMENT aan toevoegde. Dit was dan de unieke identifier van elke rij.
Ik lees dat je in PostgreSQL een automatische kolom OID (Object IDentifier) hebt. En als je een INSERT query doet krijg je ook het OID gereturned. Moet ik nu een serial veld maken, of gewoon de OID gebruiken?
En als ik het OID moet gebruiken, welke sequence moet ik dan opgeven bij de functie PDO->lastInsertId()?
Alvast bedankt voor de antwoorden!
pgSQL-handleiding:
Kortom, niet meer gebruiken, is vervallen.
Gevolg: PDO->lastInsertId() is waardeloos... Helaas, het is niet anders.
Oplossing: Gebruik een SERIAL of een INT met een SEQUENCE. Wanneer je versie 8.2 of later gebruikt, 8.3 is al in Beta, dan kun je met RETURNING het id teruggeven na een INSERT-query:
Fetch het resultaat en klaar is kees.
Mocht je een oudere versie gebruiken of iets meer controle willen hebben, haal dan eerst met NEXTVAL() de volgende waarde uit de sequence op. Die zet je in je INSERT en klaar ben je. Je weet vooraf dus al wat het id gaat worden.
Fetch dit resultaat, bv. in $id en dan de daadwerkelijke INSERT:
Klaar!
Uit de Quote:
The use of OIDs in user tables is considered deprecated
Kortom, niet meer gebruiken, is vervallen.
Gevolg: PDO->lastInsertId() is waardeloos... Helaas, het is niet anders.
Oplossing: Gebruik een SERIAL of een INT met een SEQUENCE. Wanneer je versie 8.2 of later gebruikt, 8.3 is al in Beta, dan kun je met RETURNING het id teruggeven na een INSERT-query:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
INSERT INTO
tabelnaam(
kolom,
kolom2
)
VALUES(
'waarde 1',
'waarde 2'
)
RETURNING id;
tabelnaam(
kolom,
kolom2
)
VALUES(
'waarde 1',
'waarde 2'
)
RETURNING id;
Fetch het resultaat en klaar is kees.
Mocht je een oudere versie gebruiken of iets meer controle willen hebben, haal dan eerst met NEXTVAL() de volgende waarde uit de sequence op. Die zet je in je INSERT en klaar ben je. Je weet vooraf dus al wat het id gaat worden.
Fetch dit resultaat, bv. in $id en dan de daadwerkelijke INSERT:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
INSERT INTO
tabelnaam(
id,
kolom,
kolom2
)
VALUES(
$id,
'waarde 1',
'waarde 2'
);
tabelnaam(
id,
kolom,
kolom2
)
VALUES(
$id,
'waarde 1',
'waarde 2'
);
Klaar!
Quote:
Returns the ID of the last inserted row, or the last value from a sequence object, depending on the underlying driver. For example, PDO_PGSQL() requires you to specify the name of a sequence object for the name parameter.
Zie PDO->lastInserId
Kan ik hier niet uit opmaken dat ik ook zo'n soort constructie kan gebruiken?:
Of is zoiets af te raden?
RETURNING gaat niet lukken, want ik het PostgreSQL 8.0.8. Helaas...
Vergeet de functie lastinsertid(), en ga eerst met een SELECT-query het volgende nummertje uit de SEQUENCE ophalen. Dat is een eenvoudige manier om vooraf al te bepalen wat het id gaat worden. Dit is zet je in de query en klaar ben je.
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
// maak een object in $db en dan:
$db->query("SELECT NEXTVAL('tabel_id_seq') AS id;");
$id = $db->fetchColumn();
echo $id; // dit id zet je in de volgende INSERT
?>
// maak een object in $db en dan:
$db->query("SELECT NEXTVAL('tabel_id_seq') AS id;");
$id = $db->fetchColumn();
echo $id; // dit id zet je in de volgende INSERT
?>
Edit:
Vergeet niet dat dit boek stamt uit 2001-2002 en pgSQL versie 7.1 beschrijft. Er ondertussen een hoop zaken veranderd/verbeterd. De basis is hetzelfde, maar vergeet niet om de handleiding er bij te houden.
Gewijzigd op 01/01/1970 01:00:00 door Frank -
Code (php)
1
INSERT INTO berichten (bericht,userID,titel) VALUES ('dit is een bericht',CURRENTVAL('sequence_van_id_in_tabel_users'),'dit is de titel')
Gewijzigd op 01/01/1970 01:00:00 door Lasse
Offtopic: Een CURRENTVAL() opnemen in een INSERT zou ik zelf niet snel doen, dan zal ik toch eerst een aparte SELECT-query uitvoeren om deze data op te halen. Dan weet je vooraf al wat het gaat worden en kun je dit gegeven op diverse plaatsen gebruiken: SQL en PHP.
Gewijzigd op 01/01/1970 01:00:00 door Frank -
Nog een reactie op je edit: Kan ik ook ergens een overzichtje vinden met belangrijke veranderingen tussen versie 7 en versie 8? Anders moet ik die hele handleiding doorspitten. En dat zie ik ook niet zitten...
Tip: Pak de handleiding van jouw versie erbij en leg die naast het boek waar je mee bezig bent. Mochten dingen echt heel anders zijn, zie je dat snel genoeg.
En er is altijd hulp te vinden op phphulp, maak je geen zorgen.
Frank, PostgreSQL 8.3.0 + PDO en het gebruik van RETURNING gaat toch niet samen of maak ik een denkfout? Een simpel voorbeeldje;
$sql = "INSERT INTO users.users (name) VALUES ('Arjan Kapteijn') RETURNING id";
$results = $db->exec($sql);
Die exec() returned toch altijd 1, het aantal rijen wat hij heeft ingevoegd en _niet_ het returning id...
Gewijzigd op 01/01/1970 01:00:00 door Arjan Kapteijn
Klopt Arjan. Niks meer aan toe te voegen ;)
Zie ook dit script waar query() (query zonder parameters) en excecute() (prepared statement) worden gebruikt voor INSERT, UPDATE en DELETE-queries.
@Crispijn: Klopt dus niet, gelukkig niet!
Edit: Zie RETURNING
Gewijzigd op 01/01/1970 01:00:00 door Frank -