Programando SQLite en C Tutorial Dos

Este tutorial es el segundo de una serie sobre programación de SQLite en C.

SQLite almacena una colección de tablas en una base de datos de un solo archivo, que generalmente termina en .db. Cada tabla es como una hoja de cálculo, consta de varias columnas y cada fila tiene valores.

Si ayuda, piense en cada fila como una estructura, con las columnas en la tabla correspondientes a los campos en la estructura.

Una tabla puede tener tantas filas como quepan en un disco. Hay un límite superior pero sus 18,446,744,073,709,551,616 enormes para ser precisos.

Una tabla puede tener hasta 2,000 columnas o si recompila la fuente, puede maximizarla a un increíble 32,767 columnas.

La API SQLite

Para usar SQLite, necesitamos hacer llamadas a la API. Puede encontrar una introducción a esta API en la página web oficial Introducción a la interfaz SQLite C / C ++. Es una colección de funciones y fácil de usar..

Primero, necesitamos un identificador para la base de datos. Este es de tipo sqlite3 y se devuelve mediante una llamada a sqlite3_open (nombre de archivo, ** ppDB). Después de eso, ejecutamos el SQL.

Sin embargo, primero tengamos una ligera digresión y creemos una base de datos utilizable y algunas tablas con SQLiteSpy. (Consulte el tutorial anterior para obtener enlaces a eso y al Explorador de bases de datos SQLite).

Eventos y lugares

La base de datos about.DB tendrá tres tablas para gestionar eventos en varios lugares. Estos eventos serán fiestas, discotecas y conciertos y se llevarán a cabo en cinco lugares (alfa, beta, charlie, delta y echo). Cuando está modelando algo como esto, a menudo ayuda comenzar con una hoja de cálculo. Por simplicidades, solo guardaré una fecha, no una hora.

La hoja de cálculo tiene tres columnas: Fechas, Lugar, Tipo de evento y unos diez eventos como este. Fechas del 21 al 30 de junio de 2013.

Ahora SQLite no tiene un tipo de fecha explícito, por lo que es más fácil y rápido almacenarlo como int y de la misma manera que Excel usa fechas (días desde el 1 de enero de 1900) tiene valores int 41446 a 41455. Si coloca las fechas en una hoja de cálculo luego formatee la columna de fecha como un número con 0 decimales, se ve así:

Ahora podríamos almacenar estos datos en una tabla y para un ejemplo tan simple, probablemente sería aceptable. Sin embargo, las buenas prácticas de diseño de bases de datos requieren cierta normalización.

Los elementos de datos únicos como el tipo de lugar deben estar en su propia tabla y los tipos de eventos (fiesta, etc.) también deben estar en uno. Finalmente, como podemos tener múltiples tipos de eventos en múltiples lugares, (una relación de muchos a muchos) necesitamos una tercera mesa para mantener estos.

Las tres tablas son:

  • Sedes - contiene los cinco lugares
  • eventtypes: contiene los tres tipos de eventos
  • eventos: contiene la fecha más la identificación del lugar más la identificación del tipo de evento. También agregué un campo de descripción para este evento, por ejemplo, "Cumpleaños de Jim".

Las dos primeras tablas contienen los tipos de datos, por lo que los lugares tienen nombres alfa para hacer eco. También agregué una identificación entera y creé un índice para eso. Con el pequeño número de lugares (5) y tipos de eventos (3), podría hacerse sin un índice, pero con tablas más grandes, se volverá muy lento. Entonces, cualquier columna en la que se pueda buscar, agregue un índice, preferiblemente entero

El SQL para crear esto es:

El índice en la tabla de eventos tiene fecha, id-event, tipo de evento y lugar. Eso significa que podemos consultar la tabla de eventos para "todos los eventos en una fecha", "todos los eventos en un lugar", "todas las fiestas", etc. y combinaciones de aquellos como "todas las fiestas en un lugar", etc..

Después de ejecutar las consultas de creación de tablas de SQL, se crean las tres tablas. Tenga en cuenta que he puesto todo ese sql en el archivo de texto create.sql e incluye datos para llenar algunas de las tres tablas.

Si pones ; al final de las líneas, como lo hice en create.sql, puede procesar y ejecutar todos los comandos de una vez. Sin el ; Tienes que ejecutar cada uno por sí mismo. En SQLiteSpy, simplemente haga clic en F9 para ejecutar todo.

También he incluido sql para colocar las tres tablas dentro de los comentarios de varias líneas usando / * ... * / igual que en C. Simplemente seleccione las tres líneas y haga ctrl + F9 para ejecutar el texto seleccionado.

Estos comandos insertan los cinco lugares:

Nuevamente, he incluido texto comentado en tablas vacías, con el eliminar de líneas. No hay deshacer, así que ten cuidado con estos!

Sorprendentemente, con todos los datos cargados (ciertamente no mucho), el archivo completo de la base de datos en el disco es de solo 7 KB.

Datos del evento

En lugar de crear un conjunto de diez declaraciones de inserción, utilicé Excel para crear un archivo .csv para los datos del evento y luego utilicé la utilidad de línea de comandos SQLite3 (que viene con SQLite) y los siguientes comandos para importarlo.

Nota: Cualquier línea con un prefijo de punto (.) Es un comando. Use .help para ver todos los comandos. Para ejecutar SQL simplemente escríbalo sin prefijo de punto.

Debe usar barras negras dobles \\ en la ruta de importación para cada carpeta. Solo haga la última línea después de que .import haya tenido éxito. Cuando SQLite3 se ejecuta, el separador predeterminado es un: por lo que debe cambiarse a una coma antes de la importación.

Regresar al Código

Ahora que tenemos una base de datos completamente poblada, escribamos el código C para ejecutar esta consulta SQL que devuelve una lista de partes, con descripción, fechas y lugares.

  • ¿Nuevo en SQL? Leer qué es SQL?

Esto hace una unión usando la columna idvenue entre la tabla de eventos y lugares para que obtengamos el nombre del lugar y no su valor int idvenue.

Funciones de SQLite C API

Hay muchas funciones, pero solo necesitamos unas pocas. El orden de procesamiento es:

  1. Abra la base de datos con sqlite3_open (), salga si tiene un error al abrirlo.
  2. Prepare el SQL con sqlite3_prepare ()
  3. Realice un bucle con slqite3_step () hasta que no haya más registros
  4. (En el bucle) procese cada columna con sqlite3_column ...
  5. Finalmente llame a sqlite3_close (db)

Hay un paso opcional después de llamar a sqlite3_prepare donde se enlazan los parámetros pasados, pero lo guardaremos para un tutorial futuro.

Entonces, en el programa que se enumera a continuación, el pseudocódigo para los pasos principales son:

El sql devuelve tres valores, por lo que si sqlite3.step () == SQLITE_ROW, los valores se copian de los tipos de columna apropiados. He usado int y texto. Muestro la fecha como un número, pero siéntase libre de convertirla en una fecha.

Listado de código de ejemplo