Conectando con bases de datos Microsoft SQL Server desde Linux

bbddPuede que te preguntes ¿para qué?

La verdad es que no creo haber visto todavía ninguna aplicación Linux que use (o siquiera presente como opción) una base de datos MS SQL Server, pero siempre es posible que queramos por ejemplo monitorizar el estado de una BBDD desde un Nagios o un HPOM (con una simple query podríamos comprobar que está levantada y accesible) o puede que necesitemos explotarla por cualquier motivo para algún desarrollo propio.

Sea como sea, dada la necesidad lo siguiente es pensar cómo diablos hacerlo.

La idea más obvia es odbc pero para ello necesitaremos un driver que nos permita conectar con SQL Server, y aquí es donde entra FreeTDS.

Necesitamos instalar lo siguiente:

  • freetds-bin
  • tdsodbc
  • unixodbc

Además si vamos a realizar las queries con perl, instalaremos:

  • perl (obviamente)
  • libdbi-perl

Con estos prerrequisitos preparados lo siguiente es configurar la conexión. Empezaremos por el FreeTDS, cuyo archivo de configuración freetds.conf estará en /etc o en /etc/freetds dependiendo de la distribución Linux que estemos usando.

Añadiremos un párrafo como éste para cada host SQL Server al que queramos conectar:

[hostsql1]
host = 192.168.0.30
port = 1433
tds version = 8.0
  • [hostsql1] → ponemos el identificador que queramos.
  • host → el hostname o IP del servidor SQL.
  • port → el puerto de conexión a la base de datos, por defecto 1433.
  • tds version → para SQL Server 2008 nos valdrá la versión 8.0 de TDS, si conectamos con SQL 2000 es posible que necesitemos seleccionar la versión 7.0 o 7.2.

Ya tenemos el TDS listo para una conexión, el siguiente paso es configurar nuestro ODBC.

Empezamos por el /etc/odbcinst.ini donde configuraremos el driver a utilizar. Añadimos un párrafo como éste para las conexiones a SQL Server:

La ruta a estas librerías puede ser diferente en tu distribución, puedes buscarlas con “sudo find / -name libtds*.so”
[ms-sql]
Description = TDS connection
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so
UsageCount = 1
FileUsage = 1

Guardamos el archivo y pasamos a editar /etc/odbc.ini, donde configuraremos la conexión a una base de datos en concreto:

[odbc-dbname]
Description = sqlserver1
Driver = ms-sql
ServerName = hostsql1
UID = TuUsuario
Port = 1433
Database = dbname

Aquí son especialmente importantes dos cosas no del todo obvias:

  • Driver debe de ser el nombre del driver que hemos definido en odbcinst.ini
  • ServerName debe de ser el identificador de host que hemos definido en freetds.conf

Con esto deberíamos tener ya todo preparado, así que vamos a probar:

# tsql -S 192.168.0.30 -p 1433 -U TuUsuario -P TuPassword
locale is “en_US.UTF-8″
locale charset is “UTF-8″
1>
# isql -v odbc-dbname TuUsuario TuPassword

| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+—————————————+

SQL>

Si obtenemos este resultado en ambas pruebas, felicidades, todo funciona correctamente. Si no, toca revisar la configuración.

Último objetivo: lanzar nuestras queries desde un script perl usando todo esto que acabamos de conseguir.

#!/usr/bin/perl -w
use DBI;

my $user = 'TuUsuario';
my $passwd = 'TuPassword';

my $db_options = {
PrintError => 0,
RaiseError => 1,
AutoCommit => 1, 
};

my $dbh =
DBI->connect('dbi:ODBC:odbc-dbname', $user, $passwd, $db_options)
or exit_msg("Can't connect: $DBI::errstr");
my $sql="select 1";
my $sth = $dbh->prepare($sql); $sth->execute();

while (@row= $sth->fetchrow_array()) {
print "$row[0]\n";
}

my $rc = $sth->finish;
exit(0);

Profit!