Wie man zu Zwecken der Automatisierung von Perl aus auf eine mySQL-Datenbank zugreift, hatte ich schonmal in einem anderen Artikel angeschnitten.

Auf eine MS-SQL-Datenbank zuzugreifen, stellte sich im Endeffekt nicht ganz so einfach heraus: Einige Tools und Installationen waren nötig, um mit Hilfe von FreeTDS eine Brücke zwischen Perl und MS-SQL zu schlagen.

Libtool installieren

Genutzt hatte ich damals Version 2.2.4 von libtool, die aktuellste Version ist hier zu finden.

Libtool muss in /usr/local installiert werden. Nachdem das Paket heruntergeladen und entpackt wurde, im Terminal in das Verzeichnis /usr/local wechseln und von dort aus installieren:

cd /usr/local
sudo [pfad des heruntergeladenen libtools]/configure
sudo make
sudo make install

 

FreeTDS installieren

Aktuelle stabile Version hier herunterladen.

Laut Anleitung  sollte man so konfigurieren:

./configure --disable-libiconv

Da die Installation allerdings in /usr/local erfolgen soll:

./configure --disable-libiconv --prefix=/usr/local --libdir=/usr/local/lib

Danach überschreiben wir das in FreeTDS enthaltene libtool durch einen Symbolic Link mit unserem zuvor installieren:

ln -sf /usr/local/bin/libtool

...und installieren...

make
sudo make install

Bekannte Probleme mit FreeTDS: Nach einigen Jahren der Nutzung stolperte ich bei der Einrichtung eines neuen Workflows darüber, dass mir bei Datenbankeinträgen, die einen längeren Text enthielten, der Text nach 80 Zeichen abgeschnitten wurde.
Dank Google musste ich bei meinen Skripten nicht lange nach dem Fehler suchen: Der Fehler lag an FreeTDS (genutzte Version 0.83).
Der Bug ist inzwischen behoben: Ich führte wie oben beschrieben eine erneute FreeTDS-Installation mit der aktuellen Version 0.91 durch und hatte keinen abgeschnittenen Text mehr.

Config-Datei anpassen

Die Config-Datei liegt in /usr/local/etc/freetds.conf und sieht bei mir wie folgt aus:

[global]
        # TDS protocol version
        tds version = 8.0

        # Whether to write a TDSDUMP file for diagnostic purposes
        # (setting this to /tmp is insecure on a multi-user system)
;       dump file = /tmp/freetds.log
;       debug flags = 0xffff

        # Command and connection timeouts
;       timeout = 10
;       connect timeout = 10

        # If you get out-of-memory errors, it may mean that your client
        # is trying to allocate a huge buffer for a TEXT field.
        # Try setting 'text size' to a more reasonable limit
        text size = 64512

[meine_datenbank]
        host = 172.17.60.94
        port = 1433
        tds version = 8.0

[meine_andere_datenbank]
        host = 172.17.60.94
        instance = instanzname
        tds version = 8.0

Bei der Umstellung des Datenbank-Servers musste ich feststellen, dass meine damalige Konfiguration mit host und port nicht mehr funktionierte.

Ein kurzes (aber trotzdem mit Schweißausbrüchen behaftetes) Googlen und etwas Testerei brachte die Lösung, dass die Angabe des Ports entfernt werden (!) und stattdessen ein Instanzname angegeben werden muss (siehe Eintrag [meine_andere_datenbank]).

Der Instanzname wird bei der Konfiguration der Datenbank vergeben und ist wohl vonnöten, wenn zwei Datenbanken parallel auf einem Server betrieben werden (habe die Datenbank nicht selbst eingerichtet).

Testen

TDSVER=8.0 tsql -H 'meine_datenbank' -p 1433 -U datenbank_benutzername -P datenbank_passwort

 

CPAN-DBI-Modul installieren (Falls noch nicht vorhanden)

perl -MCPAN -e 'shell'
cpan> get DBI
cpan> exit
sudo perl -MCPAN -e 'install DBI'

 

CPAN-Sybase-Modul installieren

Damit wir auch letztendlich von Perl aus auf die Datenbank zugreifen können.
Das Modul gibt's hier bei CPAN.

export SYBASE=/usr/local
perl Makefile.PL
make
make test
sudo make install

 

Letztendliche Nutzung (Beispiel)

#!/usr/bin/perl
use DBI;
my $db  = DBI->connect('dbi:Sybase:server=meine_datenbank;database=KUNDEN', 'BENUTZERNAME', 'PASSWORT');
my $q    = $db->prepare("select * from Companys where cname like ?");
$q->execute("acme") or die("Datenbankfehler.");
while (my @c = $q->fetchrow_array()) {
   printf $c[0], ", ";
  }
$q->finish();
$db->disconnect();