SQLite programmeren in C Tutorial Two

Deze tutorial is de tweede in een serie over het programmeren van SQLite in C.

SQLite slaat een verzameling tabellen op in een enkele bestandsdatabase, meestal eindigend op .db. Elke tabel is als een spreadsheet, het bestaat uit een aantal kolommen en elke rij heeft waarden.

Als het helpt, beschouw elke rij dan als een struct, waarbij de kolommen in de tabel overeenkomen met de velden in de struct.

Een tabel kan zoveel rijen bevatten als op een schijf passen. Er is een bovengrens maar de enorme 18.446.744.073.709.551.616 om precies te zijn.

Een tabel kan maximaal 2.000 kolommen bevatten of als u de bron opnieuw compileert, kunt u deze maximaal 32.767 kolommen gebruiken.

De SQLite API

Om SQLite te gebruiken, moeten we de API aanroepen. U kunt een inleiding tot deze API vinden op de officiële introductie tot SQLite C / C ++ interface webpagina. Het is een verzameling functies en gemakkelijk te gebruiken.

Eerst hebben we een handvat nodig voor de database. Dit is van het type sqlite3 en wordt geretourneerd door een aanroep naar sqlite3_open (bestandsnaam, ** ppDB). Daarna voeren we de SQL uit.

Laten we eerst een kleine uitweiding hebben en een bruikbare database en enkele tabellen maken met SQLiteSpy. (Zie de vorige zelfstudie voor koppelingen naar die en de SQLite-databasebrowser).

Evenementen en locaties

De database about.DB zal drie tabellen bevatten om evenementen op verschillende locaties te beheren. Deze evenementen zijn feesten, disco's en concerten en vinden plaats op vijf locaties (alpha, beta, charlie, delta en echo). Wanneer u zoiets modelleert, helpt het vaak om met een spreadsheet te beginnen. Omwille van de eenvoud bewaar ik gewoon een datum en geen tijd.

De spreadsheet heeft drie kolommen: datums, locatie, type evenement en ongeveer tien evenementen zoals deze. Datums lopen van 21 tot 30 juni 2013.

SQLite heeft nu geen expliciet datumtype, dus het is gemakkelijker en sneller om het op te slaan als een int en op dezelfde manier waarop Excel datums gebruikt (dagen sinds 1 januari 1900) hebben int-waarden 41446 tot 41455. Als u de datums in een spreadsheet plaatst formatteer vervolgens de datumkolom als een getal met 0 decimalen, het ziet er ongeveer zo uit:

Nu zouden we deze gegevens in één tabel kunnen opslaan en voor zo'n eenvoudig voorbeeld zou het waarschijnlijk acceptabel zijn. Goede praktijken bij het ontwerpen van databases vereisen echter enige normalisatie.

Unieke gegevensitems zoals het type locatie moeten in een eigen tabel staan ​​en de gebeurtenistypen (partij, enz.) Moeten er ook in staan. Ten slotte, omdat we meerdere gebeurtenistypen op meerdere locaties kunnen hebben (een veel-te-veel-relatie), hebben we een derde tafel nodig om deze te houden.

De drie tabellen zijn:

  • locaties - bevat alle vijf locaties
  • evenementtypen - bevat alle drie soorten evenementen
  • evenementen - bevat de datum plus locatie-ID plus evenementtype-ID. Ik heb ook een beschrijvingsveld voor dit evenement toegevoegd, bijvoorbeeld "Jim's Birthday".

De eerste twee tabellen bevatten de gegevenstypen, zodat locaties de namen alfa tot echo hebben. Ik heb ook een integer-ID toegevoegd en daarvoor een index gemaakt. Met het kleine aantal locaties (5) en gebeurtenistypen (3) kan dit zonder een index, maar met grotere tabellen wordt het erg langzaam. Dus elke kolom waarnaar waarschijnlijk wordt gezocht, voegt een index toe, bij voorkeur een geheel getal

De SQL om dit te maken is:

De index op de evenemententabel bevat datum, id-evenement, het type evenement en locatie. Dat betekent dat we de evenemententabel kunnen opvragen voor "alle evenementen op een datum", "alle evenementen op een locatie", "alle partijen" enz. En combinaties daarvan zoals "alle partijen op een locatie" enz..

Na het uitvoeren van de SQL-tabelquery's, worden de drie tabellen gemaakt. Opmerking Ik heb al die sql in het tekstbestand create.sql geplaatst en bevat gegevens voor het invullen van enkele van de drie tabellen.

Als je zet; aan het einde van de regels, zoals ik heb gedaan in create.sql, dan kun je alle opdrachten in één keer in batches uitvoeren en uitvoeren. Zonder de ; je moet ze allemaal alleen uitvoeren. Klik in SQLiteSpy op F9 om alles uit te voeren.

Ik heb ook sql toegevoegd om alle drie de tabellen in opmerkingen met meerdere regels te verwijderen met / * ... * / hetzelfde als in C. Selecteer gewoon de drie regels en voer Ctrl + F9 uit om de geselecteerde tekst uit te voeren.

Met deze opdrachten worden de vijf locaties ingevoegd:

Wederom heb ik uitgecommentarieerde tekst opgenomen in lege tabellen, met de verwijderen uit lijnen. Er is geen ongedaan maken dus wees voorzichtig met deze!

Verbazingwekkend genoeg is met alle geladen gegevens (toegegeven niet veel) het hele databasebestand op schijf slechts 7 KB.

Evenementgegevens

In plaats van een stel van tien invoeginstructies op te bouwen, gebruikte ik Excel om een ​​CSV-bestand voor de gebeurtenisgegevens te maken en gebruikte ik vervolgens het opdrachtregelprogramma SQLite3 (dat wordt geleverd bij SQLite) en de volgende opdrachten om het te importeren.

Opmerking: elke regel met een voorvoegsel (.) Is een opdracht. Gebruik .help om alle opdrachten te bekijken. Om SQL uit te voeren typt u het gewoon in zonder puntprefix.

U moet dubbele blackslashes \\ gebruiken in het importpad voor elke map. Voer de laatste regel pas uit als de .import is geslaagd. Wanneer SQLite3 wordt uitgevoerd, is het standaardscheidingsteken a: dus moet dit vóór de import worden gewijzigd in een komma.

Terug naar de code

Nu hebben we een volledig gevulde database, laten we de C-code schrijven om deze SQL-query uit te voeren die een lijst met partijen retourneert, met een beschrijving, datums en locaties.

  • Nieuw bij SQL? Lees wat SQL is?

Dit doet een join met behulp van de idvenue-kolom tussen de tabel met evenementen en locaties, dus we krijgen de naam van de locatie, niet de int idvenue-waarde.

SQLite C API-functies

Er zijn veel functies, maar we hebben maar een handvol nodig. De volgorde van verwerking is:

  1. Open de database met sqlite3_open (), sluit af als er een fout is opgetreden bij het openen.
  2. Bereid de SQL voor met sqlite3_prepare ()
  3. Loop met slqite3_step () totdat er geen records meer zijn
  4. (In de lus) verwerk elke kolom met sqlite3_column…
  5. Bel ten slotte sqlite3_close (db)

Er is een optionele stap na het aanroepen van sqlite3_prepare waarbij alle doorgegeven parameters zijn gebonden, maar we bewaren dat voor een toekomstige zelfstudie.

Dus in het onderstaande programma is de pseudocode voor de belangrijkste stappen:

De sql retourneert drie waarden, dus als sqlite3.step () == SQLITE_ROW worden de waarden uit de juiste kolomtypen gekopieerd. Ik heb int en tekst gebruikt. Ik geef de datum weer als een getal, maar voel je vrij om deze om te zetten in een datum.

Lijst met voorbeeldcodes