poniedziałek, 24 września 2018

SQLite - C / C ++


SQLite - C / C ++
W tym rozdziale nauczysz się korzystać z SQLite w programach C/C++.
Instalacja
Zanim zaczniesz używać SQLite w naszych programach C/C++, upewnij się, że masz zainstalowaną bibliotekę SQLite na komputerze. Możesz sprawdzić rozdział Instalacja SQLite, aby zrozumieć proces instalacji.

Interfejsy API interfejsu C/C++

Poniżej przedstawiono ważne procedury interfejsu SQLite C/C ++, które mogą wystarczyć do pracy z bazą danych SQLite z programu C/C++. Jeśli szukasz bardziej wyrafinowanej aplikacji, możesz przejrzeć oficjalną dokumentację SQLite.
L.p.
API i opis
1
sqlite3_open (const char * filename, sqlite3 ** ppDb)
Ta procedura otwiera połączenie z plikiem bazy danych SQLite i zwraca obiekt połączenia z bazą danych, który ma być używany przez inne procedury SQLite.
Jeśli argument filename ma wartość NULL lub ":memory:", funkcja sqlite3_open() utworzy bazę danych w pamięci RAM, która będzie działać tylko przez czas trwania sesji.
Jeśli nazwa pliku nie ma wartości NULL, program sqlite3_open() spróbuje otworzyć plik bazy danych, używając jego wartości. Jeśli nie istnieje plik o tej nazwie, program sqlite3_open() otworzy nowy plik bazy danych o tej nazwie.
2
sqlite3_exec (sqlite3 *, const char * sql, sqlite_callback, void * data, char ** errmsg)
Ta procedura zapewnia szybki i łatwy sposób wykonywania poleceń SQL dostarczanych przez argument sql, który może składać się z więcej niż jednego polecenia SQL.
Tutaj pierwszy argument sqlite3 jest obiektem otwartej bazy danych, sqlite_callback jest wywołaniem, dla którego dane są pierwszym argumentem, a errmsg zostanie zwrócony, aby uchwycić każdy błąd wywołany przez procedurę.
Funkcja SQLite3_exec() analizuje i wykonuje każde polecenie podane w argumencie sql, dopóki nie dojdzie do końca łańcucha lub nie wystąpi błąd.
3
sqlite3_close(sqlite3*)
Ta procedura zamyka połączenie z bazą danych, które zostało wcześniej otwarte przez wywołanie metody sqlite3_open(). Wszystkie przygotowane instrukcje związane z połączeniem powinny zostać sfinalizowane przed zamknięciem połączenia.
Jeśli pozostaną jakieś zapytania, które nie zostały sfinalizowane, funkcja sqlite3_close() zwróci SQLITE_BUSY z komunikatem o błędzie Nie można zamknąć z powodu niezakończonych instrukcji.

Połączenie z bazą danych

Poniższy segment kodu C pokazuje, jak połączyć się z istniejącą bazą danych. Jeśli baza danych nie istnieje, to zostanie utworzona i wreszcie zostanie zwrócony obiekt bazy danych.
#include <stdio.h>
#include <sqlite3.h>

int main(int argc, char* argv[]) {
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;

   rc = sqlite3_open("test.db", &db);

   if( rc ) {
      fprintf(stderr, "Nie można otworzyć bazy: %s\n", sqlite3_errmsg(db));
      return(0);
   } else {
      fprintf(stderr, "Otworzono bazę pomyślnie\n");
   }
   sqlite3_close(db);
}
A teraz możemy skompilować i uruchomić powyższy program do tworzenia naszej bazy danych test.db w bieżącym katalogu. Możesz zmienić ścieżkę zgodnie z wymaganiami.
$gcc test.c -l sqlite3
$./a.out
Otworzono bazę pomyślnie
Jeśli masz zamiar użyć kodu źródłowego C++, wtedy można skompilować kod w następujący sposób -
$g++ test.c -l sqlite3
Tutaj łączymy nasz program z biblioteką sqlite3 i dostarczamy wymaganych funkcji do programu C. Spowoduje to utworzenie pliku bazy danych test.db w twoim katalogu, a otrzymasz następujący wynik.
-rwxr-xr-x. 1 root root 7383 May 8 02:06 a.out
-rw-r--r--. 1 root root  323 May 8 02:05 test.c
-rw-r--r--. 1 root root    0 May 8 02:06 test.db

Utwórz tabelę

Następujący segment kodu C zostanie użyty do utworzenia tabeli w poprzednio utworzonej bazie danych -
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>

static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
   int i;
   for(i = 0; i<argc; i++) {
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[]) {
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;

   /* Otworzenie bazy */
   rc = sqlite3_open("test.db", &db);
  
   if( rc ) {
      fprintf(stderr, "Nie można otworzyć bazy danych: %s\n", sqlite3_errmsg(db));
      return(0);
   } else {
      fprintf(stdout, "Bazę otwarto pomyślnie\n");
   }

   /* Utwórz instrukcję SQL */
   sql = "CREATE TABLE PRACOWNIK("  \
         "ID INT PRIMARY KEY     NOT NULL," \
         "NAZWISKO       TEXT    NOT NULL," \
         "WIEK           INT     NOT NULL," \
         "ADRES          CHAR(50)," \
         "PENSJA         REAL );";

   /* Wykonaj instrukcję SQL */
   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
  
   if( rc != SQLITE_OK ){
   fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   } else {
      fprintf(stdout, "Tabelę utworzono pomyślnie\n");
   }
   sqlite3_close(db);
   return 0;
}
Kiedy powyższy program zostanie skompilowany i wykonany, utworzy tabelę PRACOWNIK w bazie test.db, a końcowy listing pliku będzie następujący:
-rwxr-xr-x. 1 root root 9567 May 8 02:31 a.out
-rw-r--r--. 1 root root 1207 May 8 02:31 test.c
-rw-r--r--. 1 root root 3072 May 8 02:31 test.db

Operacja WSTAW

Poniższy segment kodu C pokazuje, w jaki sposób można tworzyć rekordy w tabeli PRACOWNIK utworzonej w powyższym przykładzie -
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>

static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
   int i;
   for(i = 0; i<argc; i++) {
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[]) {
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;

   /* Otwórz bazę */
   rc = sqlite3_open("test.db", &db);
  
   if( rc ) {
      fprintf(stderr, "Nie można otworzyć bazy: %s\n", sqlite3_errmsg(db));
      return(0);
   } else {
      fprintf(stderr, "Bazę otworzono pomyślnie\n");
   }

   /* Utwórz instrukcję SQL */
   sql = "INSERT INTO PRACOWNIK (ID,NAZWISKO,WIEK,ADRES,PENSJA) "  \
         "VALUES (1, 'Paweł', 32, 'Warszawa', 2000.00 ); " \
         "INSERT INTO PRACOWNIK (ID,NAZWISKO,WIEK,ADRES,PENSJA) "  \
         "VALUES (2, 'Adam', 25, 'Marki', 1500.00 ); "     \
         "INSERT INTO PRACOWNIK (ID,NAZWISKO,WIEK,ADRES,PENSJA)" \
         "VALUES (3, 'Tadeusz', 23, 'Ząbki', 2000.00 );" \
         "INSERT INTO PRACOWNIK (ID,NAZWISKO,WIEK,ADRES,PENSJA)" \
         "VALUES (4, 'Marek', 25, 'Kobyłka', 6500.00 );";

   /* Wykonaj instrukcję SQL */
   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
  
   if( rc != SQLITE_OK ){
      fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   } else {
      fprintf(stdout, "Rekord utworzony pomyślnie\n");
   }
   sqlite3_close(db);
   return 0;
}
Gdy powyższy program zostanie skompilowany i wykonany, utworzy on podane rekordy w tabeli PRACOWNIK i wyświetli następujące dwa wiersze:
Bazę otworzono pomyślnie
Rekord utworzony pomyślnie

Operacja SELECT

Zanim przejdziemy do rzeczywistego przykładu pobierania rekordów, przyjrzyjmy się szczegółom dotyczącym funkcji wywołania zwrotnego, której używamy w naszych przykładach. To wywołanie zwrotne zapewnia sposób na uzyskanie wyników z instrukcji SELECT. Ma następującą deklarację -
typedef int (*sqlite3_callback)(
   void*,    /* Dane dostarczone w 4. argumencie sqlite3_exec() */
   int,      /* Liczba kolumn w rzędzie */
   char**,   /* Tablica ciągów reprezentujących pola w rzędzie */
   char**    /* Tablica ciągów reprezentujących nazwy kolumn */
);
Jeśli powyższe wywołanie zwrotne jest podane w procedurze sqlite_exec() jako trzeci argument, SQLite wywoła tę funkcję wywołania zwrotnego dla każdego rekordu przetworzonego w każdej instrukcji SELECT wykonanej w argumencie SQL.
Poniższy segment kodu C pokazuje, w jaki sposób można pobierać i wyświetlać rekordy z tabeli PRACOWNIK utworzonej w powyższym przykładzie –
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>

static int callback(void *data, int argc, char **argv, char **azColName){
   int i;
   fprintf(stderr, "%s: ", (const char*)data);
  
   for(i = 0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
  
   printf("\n");
   return 0;
}

int main(int argc, char* argv[]) {
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;
   const char* data = "Wywołanie funkcji zwrotnej";

   /* Otworzenie bazy danych */
   rc = sqlite3_open("test.db", &db);
  
   if( rc ) {
      fprintf(stderr, "Nie można otworzyć bazy danych: %s\n", sqlite3_errmsg(db));
      return(0);
   } else {
      fprintf(stderr, "Otworzono bazę danych\n");
   }

   /* Utwórz instrukcję SQL*/
   sql = "SELECT * from PRACOWNIK";

   /* Wykonaj instrukcję SQL*/
   rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
  
   if( rc != SQLITE_OK ) {
      fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   } else {
      fprintf(stdout, "Operacja została wykonana pomyślnie\n");
   }
   sqlite3_close(db);
   return 0;
}

Operacja UPDATE

Poniższy segment kodu C pokazuje, w jaki sposób możemy użyć instrukcji UPDATE, aby zaktualizować dowolny rekord, a następnie pobrać i wyświetlić zaktualizowane rekordy z tabeli PRACOWNIK.
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>

static int callback(void *data, int argc, char **argv, char **azColName){
   int i;
   fprintf(stderr, "%s: ", (const char*)data);
  
   for(i = 0; i<argc; i++) {
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[]) {
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;
   const char* data = "Wywołaanie funkcji zwrotnej";

   /* Otworzenie bazy */
   rc = sqlite3_open("test.db", &db);
  
   if( rc ) {
      fprintf(stderr, "Nie można otworzyć bazy: %s\n", sqlite3_errmsg(db));
      return(0);
   } else {
      fprintf(stderr, "Otworzono pomyślnie bazę danych\n");
   }

   /* Utwórz scaloną instrukcję SQL*/
   sql = "UPDATE PRACOWNIK set PENSJA = 2500.00 where ID=1; " \
         "SELECT * from PRACOWNIK";

   /* Wykonaj instrukcję SQL*/
   rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
  
   if( rc != SQLITE_OK ) {
      fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   } else {
      fprintf(stdout, "Operacja została wykonana pomyślnie\n");
   }
   sqlite3_close(db);
   return 0;
}

Operacja DELETE  

Poniższy fragment kodu C pokazuje, jak możesz użyć instrukcji DELETE, aby usunąć dowolny rekord, a następnie pobrać i wyświetlić pozostałe rekordy z tabeli PRACOWNIK.
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>

static int callback(void *data, int argc, char **argv, char **azColName) {
   int i;
   fprintf(stderr, "%s: ", (const char*)data);
  
   for(i = 0; i<argc; i++) {
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[]) {
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;
   const char* data = "Wywołanie funkcji zwrotnej";

   /* Otwarcie bazy */
   rc = sqlite3_open("test.db", &db);
  
   if( rc ) {
      fprintf(stderr, "NIe można otworzyć bazy danych: %s\n", sqlite3_errmsg(db));
      return(0);
   } else {
      fprintf(stderr, "otworzono pomyślnie bazę danych\n");
   }

   /* Wykonanie instrukcji SQL */
   sql = "DELETE from PRACOWNIK where ID=2; " \
         "SELECT * from PRACOWNIK";

   /* Wykonanie instrukcji SQL */
   rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
  
   if( rc != SQLITE_OK ) {
      fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   } else {
      fprintf(stdout, "Operacja wykonana pomyślnie\n");
   }
   sqlite3_close(db);
   return 0;
}




Brak komentarzy:

Prześlij komentarz