Archief - SQL: de grootste id of laatst toegevoegd

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

exxhal

Legacy Member
Hoi, ik zoek een query welke de grootste id of het laatste id wat toegevoegd is in mijn db. eruit haalt.

Wat ik nodig heb zijn dus de laatste geg. welke zijn ingevoerd in een tabel uit mijn db.

Hoop dat het zowat duidelijk is.:crazy:

killgore

Legacy Member
der zijn zowel php als sql statements voor last inserted id op te halen :).

in php ist dacht ik mysql_last_insert_id fzo

in sql zelf weet ik het niet exact.

dJeez

Legacy Member
Die functies dienen enkel maar om de waarde van een autoincrement field op te halen van het laatste record dat je tijdens de huidige sessie hebt gecreëerd, ik weet zo nog niet of dat de exacte wens is? Een select max(id) from tabel zal anders ook wel volstaan, maar gebruik dat NOOIT om een nieuwe waarde voor een id te gaan bepalen.

exxhal

Legacy Member
Denk dat ik met "MAX from(id)" iets kan doen.

In mijn php doe ik een include welke een email stuurt van het laatst geplaatst in de db of dat is toch mijn bedoeling.

killgore

Legacy Member
dJeez zei:
Die functies dienen enkel maar om de waarde van een autoincrement field op te halen van het laatste record dat je tijdens de huidige sessie hebt gecreëerd, ik weet zo nog niet of dat de exacte wens is? Een select max(id) from tabel zal anders ook wel volstaan, maar gebruik dat NOOIT om een nieuwe waarde voor een id te gaan bepalen.

why not?

als dat allemaal binnen 1 transaction gebeurd is daar toch geen probleem mee me dunkt?

dJeez

Legacy Member
killgore zei:
why not?

als dat allemaal binnen 1 transaction gebeurd is daar toch geen probleem mee me dunkt?
Tot er 2 identieke IDs terugkomen omdat die op exact hetzelfde moment worden gegenereerd. Een transactie lost dat probleem overigens niet op. En neem het van mij aan : de kans dat het gebeurt is groter dan je denkt :p.

exxhal

Legacy Member
Alles lukt maar.....

Het id dat is weergegeven in de mail klopt niet ?
Ik krijg dit "Resource id #3" en het had 33 moeten zijn.

Als ik de qeury uitvoer in sql krijg ik wel 33 als resultaat.

query in php : mysql_query('SELECT max(id) FROM `tabel`')

n00bslayer

Legacy Member
Ik vrees dat er in dat geval een fout in de verwerking van je script is gekropen.
Kan je de desbetreffende code (verwerking én weergave van "Resource id #3") hier eens posten?

MrO

Legacy Member
mysql_insert_id() is de ENIGE goede manier om dit op te lossen.

Dit haalt de laatste id op die door de huidige instantie van de script is uitgevoerd op. Dus onafhankelijk van hoeveel andere gebruikers er op dat moment mee bezig zijn, je zit altijd juist!

exxhal

Legacy Member
MrO zei:
mysql_insert_id() is de ENIGE goede manier om dit op te lossen.

Dit haalt de laatste id op die door de huidige instantie van de script is uitgevoerd op. Dus onafhankelijk van hoeveel andere gebruikers er op dat moment mee bezig zijn, je zit altijd juist!

Dus ik moet het id ophalen welke is aangemaakt in mijn vorige php script ?
Ik begrijp het niet goed.
Werk ik dan met een sessie?
Het zit nu zo.
Eerst een invulform. welke gegevens plaats in de db.
Dan via een header naar een nieuwe pagina.
Kan ik dan het aangemaakte id meenemen?

Het is mij wel gelukt op deze manier.

HTML:
 $qSelect_berichten  = mysql_query('SELECT * FROM `invoer`') or die (mysql_error());
  while($aBerichten = mysql_fetch_array($qSelect_berichten))
  $text = $aBerichten['id'];

Waar $text staat voor het bericht in de email.
Dit geeft wel het juiste id weer.

dJeez

Legacy Member
exxhal zei:
Dus ik moet het id ophalen welke is aangemaakt in mijn vorige php script ?
Ik begrijp het niet goed.
Werk ik dan met een sessie?
Het zit nu zo.
Eerst een invulform. welke gegevens plaats in de db.
Dan via een header naar een nieuwe pagina.
Kan ik dan het aangemaakte id meenemen?
In het eerste script, dus waar je de insert doet kan je - uiteraard enkel indien je ID veld een auto_increment field is - via mysql_insert_id() de waarde ophalen die laatst werd toegekend (let wel op de opmerkingen in de PHP reference, voor BIGINT kolommen mag je die functie NIET gebruiken). De waarde die je dan bekomt kan je dus uiteraard ook in je redirect gaan doorsturen als parameter naar het tweede script, of opslaan in een sessie variabele, of in een cookie zetten, ...

Aangezien het niet echt duidelijk was wat je wou doen haalde ik ook SELECT MAX() aan, maar voor dit geval is dat dus duidelijk NIET de werkwijze die je moet hanteren - zoals ik ook al specifieerde hierboven :p.

n00bslayer

Legacy Member
killgore zei:
why not?

als dat allemaal binnen 1 transaction gebeurd is daar toch geen probleem mee me dunkt?
Een transactie is alleen voor queries die ofwel succesvol moeten worden uitgevoerd, ofwel helemaal ongedaan moeten gemaakt worden (denk bvb aan het klassieke overschrijving van één rekening naar een andere-probleem).

Als je iets wil uitvoeren dat afhankelijk is van een onveranderde tabel (tijdens het uitvoeren van deze reeks queries) gebruik je een table LOCK.

WHiSPy

Legacy Member
n00bslayer zei:
Een transactie is alleen voor queries die ofwel succesvol moeten worden uitgevoerd, ofwel helemaal ongedaan moeten gemaakt worden (denk bvb aan het klassieke overschrijving van één rekening naar een andere-probleem).

Als je iets wil uitvoeren dat afhankelijk is van een onveranderde tabel (tijdens het uitvoeren van deze reeks queries) gebruik je een table LOCK.

Table lock? Zijt ge zeker dat ge dat wilt doen? Beseft ge wel wat een table lock op dat moment doet?

Elk rdbms voorziet functies hiervoor. Als je 'n auto-number/sequence definieert, dan houdt je database sowieso in 'n aparte tabel bij welke de laatst toegewezen id voor die tabel is.

n00bslayer

Legacy Member
WHiSPy zei:
Table lock? Zijt ge zeker dat ge dat wilt doen? Beseft ge wel wat een table lock op dat moment doet?

Elk rdbms voorziet functies hiervoor. Als je 'n auto-number/sequence definieert, dan houdt je database sowieso in 'n aparte tabel bij welke de laatst toegewezen id voor die tabel is.

Ik denk nogal multi-user de laatste tijd :) en als iemand die laatst gewijzigde Id beïnvloed terwijl je zelf aan het updaten bent, zit je met foutieve data opgescheept. Kans van 1 op je weetwel, maar het zal je maar overkomen. Een exclusive die je de toegang tijdelijk ontzegt kan je overigens perfect opvangen. De kans dat je dit moet opvangen is even klein, maar dan heb je op het einde wel geen foutieve data.

WHiSPy

Legacy Member
n00bslayer zei:
Ik denk nogal multi-user de laatste tijd :) en als iemand die laatst gewijzigde Id beïnvloed terwijl je zelf aan het updaten bent, zit je met foutieve data opgescheept. Kans van 1 op je weetwel, maar het zal je maar overkomen. Een exclusive die je de toegang tijdelijk ontzegt kan je overigens perfect opvangen. De kans dat je dit moet opvangen is even klein, maar dan heb je op het einde wel geen foutieve data.

Als je multi-user denkt, dan wil je sowieso geen table lock veroorzaken. :D

De integriteit van je data is de verantwoordelijkheid van de instellingen van je rdbms en niet van je programmatuur. :)

n00bslayer

Legacy Member
WHiSPy zei:
Als je multi-user denkt, dan wil je sowieso geen table lock veroorzaken. :D

De integriteit van je data is de verantwoordelijkheid van de instellingen van je rdbms en niet van je programmatuur. :)

Een voorbeeld van wat ik bedoel, om misverstanden de wereld uit te helpen (door het nut van een table lock uit te leggen):

Gebruiker A wilt een order ingeven. Een order bestaat uit verschillende bestelde items.

Deze gebruiker insert eerst zijn order, om daarna alle bijhorende items te inserten (gekoppeld aan het orderId). Dit orderId kan je achterhalen op allerhande manieren, waaronder mysql_insert_id().

Echter, er is ook een gebruiker B. Deze gebruiker voert zijn order insert uit vlak voordat gebruiker A zijn items die bij zijn order horen, in de database wil inserten.
Als ik mij niet vergis, geeft [SIZE=-1]mysql_insert_id() de meest recente auto_increment weer, en zal deze functie dus de door gebruiker B laatst gegenereerde Id returnen.

Bijgevolg zullen alle order items onder het laatst gegenereerde order vallen, en zal de vorige order geen items hebben.

Om dit te voorkomen gebruik je een table lock. Uitlezen van gegevens heeft tijdens deze lock ook geen zin, omdat nog niet alle items van het laatste order zullen aangevuld zijn wanneer op dat ogenblik bvb een overzicht van alle orders inclusief bijhorende items wordt opgevraagd.

De tijdspanne waar ik het over heb is echt miniem, net als de kans dat dit voorvalt. Maar het is slechts een kleine moeite om dit te voorkomen.
[/SIZE]

dJeez

Legacy Member
n00bslayer zei:
Als ik mij niet vergis, geeft mysql_insert_id() de meest recente auto_increment weer, en zal deze functie dus de door gebruiker B laatst gegenereerde Id returnen.
Je vergist je, de mysql_insert_id geeft de laatste id gegenereerd door die specifieke databaseconnectie. Dat is dus die van gebruiker A zelf.

n00bslayer

Legacy Member
dJeez zei:
Je vergist je, de mysql_insert_id geeft de laatste id gegenereerd door die specifieke databaseconnectie. Dat is dus die van gebruiker A zelf.
IC :) weer iets bijgeleerd vandaag (buiten dat leren werken met AS 3.0 buitengewoon frustrerend is als je 2.0 gewoon bent).
Maar een lock blijft nuttig, al is het dan om het uitlezen van onvolledige gegevens te voorkomen tijdens een insert/update.

killgore

Legacy Member
dJeez zei:
Tot er 2 identieke IDs terugkomen omdat die op exact hetzelfde moment worden gegenereerd. Een transactie lost dat probleem overigens niet op. En neem het van mij aan : de kans dat het gebeurt is groter dan je denkt :p.

dat is onmogelijk mits ge met goed beveiligingsniveau en transacties werkt. Kan wiskundig bewezen worden en al :p.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan