[postgresql/php] last insert ID

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 19-09 08:48
In PHP heb je voor mysql de mogelijkheid een ID terug te halen mysql_insert_id(). Deze functie haalt de laatst gegenereerde id op uit de tabel, best handig.
Nu heb ik wat meer functionaliteit nodig op gebied van triggers etc. die mysql niet biedt, dus ben ik overgestapt op postgres. Deze functie bestaat niet voor postgres, dus moet het met de hand. Ik stuit daarbij op het volgende probleem:

user a insert een rij
user b insert een rij
user a vraagt de hoogste PK op
user b vraagt de hoogste PK op

user a krijgt nu het ID van de rij die user b ingevoegd heeft. Kun je vast oplossen door met lock's oid te werken (nog niet uitgezocht), maar dan moet die tabel weer dicht zonder noodzaak. Is het niet mogelijk om meteen de PK (ID) van de ingevoegde rij terug te krijgen zonder daarbij dingen te moeten afsluiten?

Beware: dit is pas het eerste topic van een lange rij postgresql vragen ;) Waarom is die verdomde handleiding dan ook zo lang :+

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Vuurvlieg
  • Registratie: Januari 2000
  • Laatst online: 18-09 15:51
Modbreak: :/Nee, deze reply draagt veel bij aan de discussie... :/

[ Voor 84% gewijzigd door NMe op 03-10-2005 21:05 ]


Acties:
  • 0 Henk 'm!

  • JaWi
  • Registratie: Maart 2003
  • Laatst online: 20-09 21:57

JaWi

maak het maar stuk hoor...

Naast de oplossing van -NMe- kun je ook gebruik maken van sequences; PostgreSQL heeft hier erg goede ondersteuning voor.

Statistics are like bikinis. What they reveal is suggestive, but what they hide is vital.


Acties:
  • 0 Henk 'm!

  • GX
  • Registratie: Augustus 2000
  • Laatst online: 14-05 09:40

GX

Nee.

Is het de OID welke je terug wilt hebben of de primary key van een table? In het laatste geval kan je, als je een goed tableontwerp aangehouden hebt, sequence-id eruit plukken.

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
Zoals JaWi al zegt. Gebruik sequences, bij voorkeur de short-hand Serial als je een vervanger voor MySQL's auto_increment zoekt.

Na de insert kan je dan gewoon SELECT curval("sequence_naam"); doen en heb je het meest recent toegewezen ID voor die sequence en dus de bijbehorende Serial-primary key. Het is iets meer werk, maar zeker ook flexibeler omdat je kan specificeren van welke sequence (tabel) je de boel wilt hebben.
Die curval is overigens binnen de transactie stabiel, dus als je nadat een andere transactie de waarde heeft aangepast de boel opvraagt heb je dezelfde waarde.

De pg_last_oid raad ik je ten strengste af omdat men in Postgresql bezig is die - meestal overbodige - oids standaard niet, ipv wel, te gebruiken.

Acties:
  • 0 Henk 'm!

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 19-09 08:48
Die OIDs heb ik in elke tabel uitgezet, kwam ergens tegen dat het deprecated is en aangezien ik een verse gebruiker ben ga ik me niet verdiepen in oude rommel. Ik heb als PK's dus inderdaad Serials gebruikt met die nextval functie om een nieuwe te genereren, dat lijkt goed te werken. SELECT curval is niet helemaal veilig denk ik (zie bovenstaande rede) maar dat heeft in mijn applicatie echt geen invloed dus ga ik dat maar gebruiken. Had het nu opgelost door de hoogste PK eruit te halen en zelfs dat ging nog redelijk goed in de tests.

@GX: goed tabelontwerp, wat versta je daar onder? Nogal een ruim begrip, maar wanneer kun je die sequence-id NIET gebruiken?

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
iCe01 schreef op dinsdag 04 oktober 2005 @ 14:29:
SELECT curval is niet helemaal veilig denk ik (zie bovenstaande rede) maar dat heeft in mijn applicatie echt geen invloed dus ga ik dat maar gebruiken.
Euh?
ACM schreef op maandag 03 oktober 2005 @ 22:24:
Die curval is overigens binnen de transactie stabiel, dus als je nadat een andere transactie de waarde heeft aangepast de boel opvraagt heb je dezelfde waarde.
Ik zie dat ik het niet helemaal duidelijk neerzette en ook niet helemaal volledig. Die curval is binnen de connectie stabiel. Dus zolang je niet uitlogt en opnieuw inlogt hou je de waarde die je in die connectie het laatst ingevoerd hebt in curval.

Uiteraard zal als user a een nieuw record in diezelfde connectie insert wel als waarde "hoogste waarde + 1" gebruikt worden en kan ie dat daarna terugvragen, maar ongeacht of er nou 100 of 0 inserts van anderen tussendoor kwamen, de curval blijft de waarde die voor die connectie afgegeven is bewaren.

Acties:
  • 0 Henk 'm!

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 19-09 08:48
Ok dat had ik niet helemaal begrepen... duidelijk nu!

Nieuw probleem :+ Ik heb zojuist mod_auth_pgsql geinstalleerd op Apache, allemaal prima gegaan. Nu heb ik een database PROMAS waarin een tabel Gebruiker zit met velden "naam" en "password". In .htaccess kun je vervolgens opgeven dat er gekeken moet worden in de database naar de juiste inlogdata, dus ik heb het volgende ingevuld:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
AuthName "My PostgreSQL Authenticator"
AuthType basic

Auth_PG_host 192.168.0.1
Auth_PG_port 5432
Auth_PG_user jasper
Auth_PG_pwd *******
Auth_PG_database PROMAS
Auth_PG_pwd_table Gebruiker
Auth_PG_uid_field naam
Auth_PG_pwd_field password

<LIMIT GET POST>
        require valid-user
</LIMIT>


Werkt niet. Foutmelding in postgres log:
code:
1
ERROR:  relation "gebruiker" does not exist


Error in httpd log:
code:
1
[Tue Oct 04 18:10:58 2005] [error] [client 192.168.0.10] PGSQL 3: ERROR:  relation "gebruiker" does not exist\n -- Query: select password from Gebruiker where naam='Jasper'


Query lijkt me toch prima. Had binnen PHP ongeveer hetzelfde probleem, maar dat kon ik oplossen door dubbele quotes rond de tabelnaam / kolomnaam te zetten... hoe zit dat precies?

Acties:
  • 0 Henk 'm!

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 19-09 08:48
En jawel: dezelfde SQL opdracht binnen psql uitvoeren geeft dezelfde fout, echter wanneer ik uitvoer:
SQL:
1
2
 
SELECT * From "Gebruiker" WHERE naam='Jasper' 


werkt het wel? :?

Grrr... ligt aan die hoofdletter, dat had ik van tevoren moeten weten :P

[ Voor 22% gewijzigd door jsiegmund op 04-10-2005 17:18 ]


Acties:
  • 0 Henk 'm!

  • jochemd
  • Registratie: November 2000
  • Laatst online: 24-08 12:31
iCe01 schreef op dinsdag 04 oktober 2005 @ 17:12:
Grrr... ligt aan die hoofdletter, dat had ik van tevoren moeten weten :P
Zoals je zelf al aangeeft: handleiding lezen.
Pagina: 1