PostgreSQL serial of OID
Hallo,
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!
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!
Uit de 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!
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!
Oke, maar uit de php-pdo handleiding haal ik dit:
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...
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...
Wat de PHP-handleiding zegt over OID's doet niet ter zake, het gaat erom wat de pgSQL-handleiding zegt. En die zegt: OID's zijn niet voor userdata, maar uitsluitend voor intern gebruik. Gebruik een SERIAL (of een INT met SEQUENCE, dat is eigenlijk hetzelfde als een SERIAL) voor userdata.
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.
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 -
Mhm, oke. Maar dan nog een vraag: Wat is eigenlijk het nut om het id naar PHP te halen als ik na een insert ook zo'n soort query kan uitvoeren:
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
Soms heb je het id nodig omdat je verschillende INSERT-queries moet uitvoeren, denk aan genormaliseerde data in meerdere tabellen wegschrijven, of dat je de user na het wegschrijven van de data het resultaat wilt tonen op pagina view.php?id=465 Dan heb je toch echt het id nodig.
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.
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 -
Oke, bedankt voor je antwoorden!
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...
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...
Zie de release-notes van de diverse versies. Helaas zijn dat er nogal wat sinds versie 7.1.... Een stuk of 60 in jouw geval!
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.
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.
Even een oud topic, maar desalnietermin past het hier wel netjes bij...
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...
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 ;)
@Arjan: Dat gaat prima samen, RETURNING kun je vergelijken met een SELECT-query, je krijgt dus een resultset retour. Dat sluit het gebruik van de methode exec() dus uit, je kiest dus de verkeerde methode om de query uit te voeren.
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
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 -




