[firebird] mysql_insert_id()

Pagina: 1
Acties:

  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 15:57
Ik ben op dit moment bezig met een webstore die moet draaien op een firebird database.
Ik moet nu alleen het id van mijn laatste insert statement hebben. Ik weet dat er voor mysql de functie mysql_insert_id is. Maar kan niets soortgelijks voor firebird vinden? Iemand een oplossing? Google bied ook geen uitkomst..

The easiest way to solve a problem is just to solve it.


  • Cyphax
  • Registratie: November 2000
  • Laatst online: 15:48

Cyphax

Moderator LNX
Ik neem dan even aan dat je PHP gebruikt? Daar kan ik ook geen functie voor vinden.
Ik heb wel dit gevonden waar je misschien wat aan hebt: http://www.web-aware.com/codesn/cs_autoinc.htm
Het is wat minder makkelijk dan met MySQL, of met SQL Server maargoed.

Saved by the buoyancy of citrus


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 16-04 11:36

pjvandesande

GC.Collect(head);

Gebruik iets als:

SQL:
1
select GEN_ID(GeneratorName, 1) from rdb$database

[ Voor 192% gewijzigd door pjvandesande op 27-12-2005 15:24 . Reden: Ik hoef er niet bij te vertellen wat ik van firebird vind ]


  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 15:57
wat bedoel je precies met het stukje:
code:
1
rdb$database


Of beter gezegd, wat doet het? Het werkt er wel mee, maar ik ben heel erg benieuwd wat het precies is.

[ Voor 48% gewijzigd door trinite_t op 27-12-2005 16:15 ]

The easiest way to solve a problem is just to solve it.


Verwijderd

trinite_t schreef op dinsdag 27 december 2005 @ 16:00:
wat bedoel je precies met het stukje:
code:
1
rdb$database


Of beter gezegd, wat doet het? Het werkt er wel mee, maar ik ben heel erg benieuwd wat het precies is.
Niets :)

Het principe is dat je bij SELECT statements een from clause moet meegeven. Door een systeemtabel te gebruiken weet je twee dingen
1) De tabel bestaat.
2) Je krijgt exact 1 record terug.

Vrij standaard trucje in de Oracle/Interbase/Firebird wereld.

Je krijgt met dit commando trouwens niet het ID van je laatste insert statement terug maar één hoger dan het ID van de laatste insert. Of die nu van jou was of niet.

Beter is het om éérst via zo'n statement een uniek ID te genereren en dat ID daarna hard in je insert SQL statement te zetten.

[ Voor 22% gewijzigd door Verwijderd op 27-12-2005 19:30 ]


  • Civil
  • Registratie: Oktober 2002
  • Laatst online: 19-04 09:21
Verwijderd schreef op dinsdag 27 december 2005 @ 19:24:
Beter is het om éérst via zo'n statement een uniek ID te genereren en dat ID daarna hard in je insert SQL statement te zetten.
Leg je daarmee (via die SELECT statement) dan een ID vast voor de volgende INSERT query ?

Als dat namelijk niet zo is, dan ben je er toch nooit zeker van dat het ID nog steeds vrij is. Er kan in de fractie van een seconde daarna wel een INSERT zijn gedaan met hetzelfde ID. Of zie ik dat verkeerd, heb totaal geen ervaring met oracle/firebird databases.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13:55
Voor Firebird/Interbase is Jan Klaasens laatste voorstel toch het beste: eerst een id genereren en dan een row toevoegen. Dan weet je tenminste welke id gebruikt gaat worden.
Civil schreef op dinsdag 27 december 2005 @ 20:15:
Leg je daarmee (via die SELECT statement) dan een ID vast voor de volgende INSERT query?
Een generator genereert gewoon oplopende waarden; als je er een waarde uithaalt dan zal een andere transactie diezelfde waarde niet meer krijgen. Dat betekent ook dat als vervolgens je INSERT-query faalt je waarschijnlijk een 'gat' in de reeks van gebruikte id's krijgt, maar dat is meestal geen probleem.

  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 15:57
Die methode gebruik ik nu ook:
Heb nu een procedure die bij een aanroep 1 opgehoogd word, dat is dat het id voor je statement!

Hartstikke bedankt!

The easiest way to solve a problem is just to solve it.


Verwijderd

Laat ik mijzelf even aanvullen.
Beter is het om éérst via zo'n statement een uniek ID te genereren en dat ID daarna hard in je insert SQL statement te zetten.
Dat is dus in het geval je geinteresseerd bent in de waarde van het ID.
Ben je dat niet kun je ook iets als dit doen

SQL:
1
insert into testtabel (ID,naam) values (Gen_ID(generator_name,1), "Een Naam")


of je eigen autoinc veld creeren door een generator te combineren met een before insert trigger.

Zelf maak ik altijd een trigger aan waarbij ik controleer of er toevallig al een waarde voor het ID wordt meegegeven. In dat geval doet de trigger niets, anders genereert de trigger een ID. Op die manier kun je als het in je programma nodig is (omdat je bv gelijk detail records wil aanmaken) de waarde van het te inserten ID opvragen maar als het niet nodig is gewoon het hele ID verhaal negeren zoals bij een autoinc veld in andere databases.

Een tweede punt is dat een generator niet per se met 1 moet worden opgehoogd. Vind je het leuker om 5 te gebruiken is er niemand die je tegenhoudt. Ook kun je de huidige waarde van de generator opvragen zonder je generator op te hogen door een 0 mee te geven. Tot slot valt een generator volledig buiten de transactiecontrolle. Hierdoor is altijd de meest actuele waarde van de generator beschikbaar en krijg je, mits je altijd je Gen_ID ophoogd (en dus geen 0 mee geeft), nooit dubbele waarden.

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
Volgens mij kan je in Firebird/Interbase gewoon aangeven dat een ID-veld automatisch een waarde toegekend krijgt van de generator en dan hoef je het ID veld ook niet op te nemen in je insert.
Ik zit nu echter op mijn werk en kan dit niet zo snel nalezen; is wel terug te lezen in de documentatie van Firebird.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13:55
Ja duh, maar de vraag was dus hoe je dat id dan kon bepalen. ;)

  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 15:57
haha, idd.
Ik heb het nu zelfs zo gedaan dat ik een functie retreive_id($tablename) aangemaakt heb (gebruikte toch al een klasse voor firebird, dus kon mooi samen).
Dit werkt nu helemaal perfect. Ben nu nog tegen een ander probleem aangelopen waar ik nog niet de oplossing van kan vinden (iets met wazige resultaten als ik de rijen van een resultaat ga tellen, en queries in het algemeen), als dat mij morgenvroeg nog niet lukt ga ik hier wel weer eens om hulp vragen O-) ... Wil eerst alles nog een keer goed doorlopen.
[edit]
even ter verduidelijking, mijn gebruikte functie (commentaar altijd welkom):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
    /**
     * Als een tabel een procedure heeft waarmee het volgende id van een rij opgevraagd kan worden,
     * wordt er door deze functie een nieuw id 'gegenereerd' (lees: opgevraagd). Bij tabellen met een procedure primary key
     * moet je deze functie dus aanroepen voordat je een INSERT statement gebruikt.
     * @param $tablename De naam van de tabel waarvan de procedure is. 
     * @return Het nieuwe id
     */
    function generateKey($tablename){
        $tablename = strtoupper($tablename);
        $result = $this->query("SELECT GEN_ID(GEN_".$tablename."_ID, 1) FROM RDB\$DATABASE");   
        $result = ibase_fetch_object($result);
        return $result->GEN_ID; // return het id
    }

[ Voor 43% gewijzigd door trinite_t op 29-12-2005 09:04 ]

The easiest way to solve a problem is just to solve it.

Pagina: 1