Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[MySQL] Last ID toekennen aan ander veld

Pagina: 1
Acties:
  • 155 views sinds 30-01-2008
  • Reageer

  • dik_voormekaar
  • Registratie: April 2003
  • Laatst online: 20-11 21:01
Ik ben bezig met een probleem waar ik maar niet uitkom.
Ik weet ook niet of het uberhaupt wel kan.
Ik heb een tabel met een message_id, een list_id en een message

SQL:
1
2
3
4
5
6
CREATE TABLE fm_messages( 
message_id INT auto_increment NOT NULL, 
list_id INT NOT NULL,
message TEXT NOT NULL, 
PRIMARY KEY(message_id) 
)

Nu wil ik op het moment dat een record aangemaakt wordt (via INSERT dus) het veld list_id automatisch de waarde laten krijgen die message_id krijgt.
(Op andere plekken gaat list_id andere waarden krijgen, maar dat is hier nog niet van belang).

Ik heb het geprobeerd met:
SQL:
1
2
3
4
INSERT into fm_messages 
(list_id, message) 
VALUES 
(LAST_INSERT_ID(), '". $message ."')

Helaas geeft dit het ID van de voorlaatste INSERT query, niet van deze.
Het kan uiteraard wel in een aparte tweede query, maar dat wil ik niet als het niet hoeft.
Hoe zou ik dit kunnen oplossen?

Verwijderd

Als het een autoincrement kolom is dan kun je in plaats van die last_insert_id die je daar hebt een SQL-subquery gooien die eigenlijk je volgende increment-value bepaalt (dus max-waarde in huidige kolom + 1).

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

[code=sql]
INSERT into fm_messages
(list_id, message)
VALUES
(message_id, '". $message ."')[/]


Hmmm dit werkt niet voor auto-increment fields....

[ Voor 23% gewijzigd door LuCarD op 28-12-2007 11:32 ]

Programmer - an organism that turns coffee into software.


  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
het nut ontgaat me een beetje... maar misschien zoiets:

SQL:
1
2
3
INSERT INTO fm_messages (message)
VALUES ('" . $message . "');
UPDATE fm_message SET list_id = message_id WHERE message_id = LAST_INSERT_ID();


waarbij de where conditie me niet eens nodig lijkt, maar voor hele grote tabellen misschien wel handig is

[ Voor 19% gewijzigd door P.O. Box op 28-12-2007 11:35 ]


Verwijderd

Je moet trouwens even in de gaten houden, zeker als je het met 2 losse querys doet (maar heel mss ook bij mijn gegeven optie) dat tussendoor iemand anders een insert kan doen waardoor het compleet in de soep loopt.

  • dik_voormekaar
  • Registratie: April 2003
  • Laatst online: 20-11 21:01
Edwardvb schreef op vrijdag 28 december 2007 @ 11:34:
het nut ontgaat me een beetje... maar misschien zoiets:

SQL:
1
2
3
INSERT INTO fm_messages (message)
VALUES ('" . $message . "');
UPDATE fm_message SET list_id = message_id WHERE message_id = LAST_INSERT_ID();


waarbij de where conditie me niet eens nodig lijkt, maar voor hele grote tabellen misschien wel handig is
Dat zijn dus twee queries. Ik wil het graag in een.

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
dik_voormekaar schreef op vrijdag 28 december 2007 @ 11:08:
(Op andere plekken gaat list_id andere waarden krijgen, maar dat is hier nog niet van belang).
Dat is wel van belang. Nu is het gewoonweg een redundant veld, dus niet doen of gebruik een speciale waarde.

Afhankelijk van wat je nou precies met list_id wil doen heb je een slecht datamodel. Dan kan iedereen je heel behulpzaam allemaal leuke queries geven (waarbij sommigen misschien wat meer op race condities moeten letten), maar als je heel eerlijk bent zijn de queries niet de echte oplossing. :)

{signature}


  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
dat kan niet volgens mij. De query zal er toch eerst in moeten, dan zal mysql er een ID aan toekennen en dan kan je die ID pas gebruiken.

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Voutloos schreef op vrijdag 28 december 2007 @ 11:41:
[...]
Dat is wel van belang. Nu is het gewoonweg een redundant veld, dus niet doen of gebruik een speciale waarde.

Afhankelijk van wat je nou precies met list_id wil doen heb je een slecht datamodel. Dan kan iedereen je heel behulpzaam allemaal leuke queries geven (waarbij sommigen misschien wat meer op race condities moeten letten), maar als je heel eerlijk bent zijn de queries niet de echte oplossing. :)
Om nou gelijk te gaan roepen dat het slecht datamodel is wel een beetje kort door de bocht.

Ik kan me best situatie voorstellen dat je een referentie naar je zelf wilt hebben. Denk bijvoorbeeld aan een forum waarbij de startpost naar zijn eigen bericht plaatst. En alle replies een referentie hebben naar de startpost.

maar je ontkomt waarschijnlijk niet aan 2 queries. en ik denk ook niet dat je het wilt.

[ Voor 5% gewijzigd door LuCarD op 28-12-2007 11:46 ]

Programmer - an organism that turns coffee into software.


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Anders lees je alleen maar de laatste 2 woorden van die zin...
LuCarD schreef op vrijdag 28 december 2007 @ 11:46:
Ik kan me best situatie voorstellen dat je een referentie naar je zelf wilt hebben.
Dus wil ik de situatie van de ts weten.
Denk bijvoorbeeld aan een forum waarbij de startpost naar zijn eigen bericht plaatst. En alle replies een referentie hebben naar de startpost.
En dat is een voorbeeld van een superredundant datamodel waarbij duidelijk de entiteit 'topic' ontbreekt. :>

[ Voor 81% gewijzigd door Voutloos op 28-12-2007 11:51 ]

{signature}


  • Kalentum
  • Registratie: Juni 2004
  • Nu online
Verwijderd schreef op vrijdag 28 december 2007 @ 11:39:
Je moet trouwens even in de gaten houden, zeker als je het met 2 losse querys doet (maar heel mss ook bij mijn gegeven optie) dat tussendoor iemand anders een insert kan doen waardoor het compleet in de soep loopt.
Niet als je gebruik maakt van verschillende databaseverbindingen per gebruiker (zoals doorgaans in een PHP/Mysql setting gebeurt). Die last_insert_id werkt op basis van database connecties en kan dus voor elke connectie weer anders zijn.

  • dik_voormekaar
  • Registratie: April 2003
  • Laatst online: 20-11 21:01
Voutloos schreef op vrijdag 28 december 2007 @ 11:47:
Dus wil ik de situatie van de ts weten.
Je moet denken aan een soort forum. De list_id wordt gebruikt om te bepalen in welke volgorde berichten geplaatst moeten worden.
In de normale situatie is list_id = message_id, dus normale (chronologische) volgorde.
1. Een bericht kan verwijderd worden. Dan wordt list_id=0, en wordt dan niet zichtbaar.
2. Een bericht kan aangepast worden. In dat geval wordt het list_id van de oude message 0, en wordt een nieuw bericht gemaakt met list_id = de message_id van de oude message.
(Berichten worden in mijn model dus nooit verwijderd, maar er wordt een nieuwe aangemaakt met een verwijzing naar de oude).

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
OK, maar dat biedt alleen maar nadelen tov een doorgaans gebruikte 'sofdelete': Een kolom IsDeleted ipv list_id en vervolgens altijd filteren op IsDeleted. :)

{signature}


  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 10:33
Voutloos schreef op vrijdag 28 december 2007 @ 11:47:
En dat is een voorbeeld van een superredundant datamodel waarbij duidelijk de entiteit 'topic' ontbreekt. :>
offtopic:
of je komt op een discussie met een boomstructuur. Waar bij je er steeds een link is naar het bericht waar de reply voor geldt. En dat is dan een andere oplossing dan GoT, waar de link tussen de artikelen helemaal niet meer genormaliseerd is. Enige verband is [message=29328809] in het bericht.

  • dik_voormekaar
  • Registratie: April 2003
  • Laatst online: 20-11 21:01
Voutloos schreef op vrijdag 28 december 2007 @ 12:26:
OK, maar dat biedt alleen maar nadelen tov een doorgaans gebruikte 'sofdelete': Een kolom IsDeleted ipv list_id en vervolgens altijd filteren op IsDeleted. :)
Een kolom isDeleted is er geweest, maar voldeed niet volledig.
Er moesten ook (zoals ik hierboven al aangaf), berichten kunnen worden gewijzigd, met behoud van het originele bericht.

Overigens betreft het hier geen echt forum met topics e.d. (hoewel ik zei dat het een soort forum was), maar meer een soort van transactie log.
Het datamodel van deze tabel heb ik hier voor dit topic vereenvoudigd.
Pagina: 1