The easiest way to solve a problem is just to solve it.
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
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 ]
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
Nietstrinite_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.
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 ]
Leg je daarmee (via die SELECT statement) dan een ID vast voor de volgende INSERT query ?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.
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.
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.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?
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
Dat is dus in het geval je geinteresseerd bent in de waarde van het ID.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.
Ben je dat niet kun je ook iets als dit doen
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.
Ik zit nu echter op mijn werk en kan dit niet zo snel nalezen; is wel terug te lezen in de documentatie van Firebird.
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
[edit]
even ter verduidelijking, mijn gebruikte functie (commentaar altijd welkom):
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.