jueves, 17 de septiembre de 2009

Consultas SQLite desde .NET

SQLite se integra muy bien con .NET, siendo muy fácil desarrollar un proyecto con esta base de datos, con unos costes muy reducidos al no tener que pagar licencias propietarias, como en el caso de Oracle o de SQL Server.

El primer paso a dar es instalarse el conector System.Data.SQLite.dll (se puede descargar de http://sqlite.phxsoftware.com). Una vez instalado, hay que hacer referencia a dicho conector mediante Project > Add Reference... (Proyecto > Añadir referencia...), buscar el conector y OK (Aceptar).

El siguiente paso es añadir al inicio del código el uso de las clases de esta librería:

using System.Data.SQLite; 

Los ejemplos que aquí se muestran están escritos en C#, pero la adaptación a VB.NET no debería suponer gran transcendencia.

En primer lugar hay que encerrar todo el proceso de acceso a la base de datos en un bloque try...catch. Dentro de este bloque comenzaremos abriendo la conexión, mediante:

SQLiteConnection sql_con = new SQLiteConnection ("DataSource=ARCHIVOBBDD;

   Version=3;New=False;Compress=True;");
sql_con.Open();

donde, ARCHIVOBBDD es el nombre del archivo de la base de datos. Si este archivo se encuentra en una ruta fija, hay que indicar toda la ruta. Si se escribe únicamente el nombre del archivo, éste debería estar ubicado en el directorio debug y release del proyecto.

A continuación se crea el comando de la sentencia a ejecutar (en este caso una consulta o SELECT):

string CommandText = "select id_empresa, nombre from EMPRESAS order by nombre";
SQLiteCommand sql_cmd = new SQLiteCommand(CommandText, sql_con);

El siguiente paso será ejecutar el comando para obtener el resultado de la consulta, el cual estará en un DataReader:

SQLiteDataReader sql_dtr = sql_cmd.ExecuteReader();

En este momento, el puntero del cursor se encuentra justo antes del primer registro. Con el método Read(), se obtenerá el siguiente registro o fila, retornando true si se leyó correctamente, o false si no se leyó, en cuyo caso se habrá alcanzado el final del resultado. La lectura de todos los registros se puede realizar dentro de un bucle como éste:

while (sql_dtr.Read())

{

   ... // Bloque para tratar los campos de la fila obtenida

}

El acceso a cada campo se realiza a modo de array con el DataReader, comenzando desde 0, que sería el primer campo, hasta n-1. También se podría acceder indicando dentro del elemento del array el nombre del campo entre comillas, en lugar del índice. Las dos siguientes líneas realizan lo mismo:

string nombreEmpresa = (string)sql_dtr[1];

string nombreEmpresa = (string)sql_dtr["nombre"];

En todos los casos hay que hacer un casting del tipo de dato (anteponiendo y encerrando entre paréntesis el tipo de dato), por lo que hay que tener especial cuidado con los datos que son numéricos o de fecha. Las siguientes líneas son una muestra de ello, aunque no tengan que ver con el ejemplo que estamos planteando:

long lData = (Int64)sql_dtr[0];  // Tipo entero largo

Single sData = (Single)sql_dtr[1];  // Tipo decimal

Double dData = (Double)sql_dtr[0];  // Tipo decimal de doble precisión

Para hacer una captura correcta de datos, lo mejor es comprobar si el dato no es nulo y un parseo en consecuencia, como en el siguiente ejemplo:

Single sCant=0;
string sData = dtr[0].ToString();
if (sData != null && sData != "")
     sCant = Single.Parse(sData);  

   

Si el dato no admite nulos, se puede realizar el parseo directamente:

long plazo = (long)long.Parse(sql_dtr[6].ToString()) ; 

Double dData = Double.Parse(sql_dtr[0].ToString());

DateTime dtFecha = DateTime.Parse(sql_dtr["fecha"].ToString());

Una vez se han leído los registros y no se vaya a utilizar más el DataReader, hay que cerrarlo para optimizar recursos:

sql_dtr.Close();

Si la conexión ya no es necesaria por el momento, cerrarla también:

sql_con.Close();

El código completo del ejemplo, es el siguiente, y su objetivo es cargar una lista de empresas en una combo (lista desplegable):


// Carga la combo de empresas
private void loadEmpresas()
{
  try
  {
    SQLiteConnection sql_con = new SQLiteConnection

      ("Data Source=ti_facturas.db;Version=3;

      New=False;Compress=True;");
    sql_con.Open();

    string CommandText =

      "select id_empresa, nombre from EMPRESAS order by nombre";
    SQLiteCommand sql_cmd = new SQLiteCommand(CommandText, sql_con);
    SQLiteDataReader sql_dtr = sql_cmd.ExecuteReader();

    DataTable dt;
    dt = new DataTable("Datos");

    dt.Columns.Add("id_empresa");
    dt.Columns.Add("empresa");

    DataRow dr;

    while (sql_dtr.Read())
    {
      dr = dt.NewRow();
      dr["id_empresa"] = ((Int64)sql_dtr[0]);
      dr["empresa"] = (string)sql_dtr[1];
      dt.Rows.Add(dr);

    }

    cboEmpresa.DataSource = dt;
    cboEmpresa.ValueMember = "id_empresa";
    cboEmpresa.DisplayMember = "empresa";

    sql_dtr.Close();
    sql_con.Close();
  }
  catch (Exception argEx)
  {
    Console.WriteLine("Exception message: " + argEx.Message);
  }
}




Safe Creative #1001195348549