jeudi 17 novembre 2011

Accéder à une base de donnée DBase / FoxPro (dbf) en PowerShell


La connection string
Avant tout, il faut une "Connection String" permettant de mentionner la DB et le Driver à utiliser.
Une visite sur www.connectionstrings.com est bien utile pour nous aider dans cette tâche.
J'ai retenu l'option suivante (voir cette page)
Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=c:\mydbpath;
Après quelques péripéties, j'en suis arrivé à utilisé un OleDB provider avec la ConnectionString suivante:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\temp\stock;Extended Properties= dBASE IV

PowerShell et Accès DB
Je vous propose les lectures suivantes pour vous familiariser avec l'écriture de code d'accès DB en PowerShell.
Installation des drivers ODBC ou Equivalent
Par defaut, mon Win7 64 bit ne dispose que des drivers ODBC pour Sql Serveur.
Voir  l'outil de configuration "Administration des sources de données ODBC"

J'ai donc besoin d'installer un driver ODBC pour attaquer DBase ou tout équivalent.
Après de longue recherche et m'être éclaté plusieurs fois la tête au mur, j'ai opté pour l'installation du Microsoft Jet Engine disponible sur le net.
Selon certaines sources, l'ACE Engine de Microsoft fonctionnerait très bien aussi.
Dans les faits, je sais qu'il est possible d'attaquer un fichier DBase avec un OleProvider Microsoft.Jet.OLEDB.4.0

Windows 64 bits, PowerShell et OleDB ou ODBC
Nous utilisons Windows Seven 64 bits et Powershell pour attaquer la DB.
Tous mes premiers essais terminait inlassablement par le message " Le fournisseur 'Microsoft.Access.OLEDB.10.0' n'est pas inscrit sur l'ordinateur local " (Arghhh!!! pffff!)
C'est a se taper la tête au mur! Si je regarde dans la base de registre, mon provider OLEDB est bien là!

Mais pourquoi ai-je donc ce message d'erreur?
Et bien mon problème réside dans le fait que j'utilise un OS 64 Bits!
D'un côté, Microsoft à bien produit un provider 64 bits pour SqlServeur mais pas de version 64 bits de Jet Engine (moteur DB d'access).
Office 2010 est toujours un logiciel 32 bit, cela inclus aussi Access et le Jet Engine (et Dieu seul sait quoi d'autre).

D'un autre côté, mon PowerShell fonctionne en 64 bits... et accède uniquement les OleDB Provider 64 bits.
En gros, je suis limité à SqlServeur!

La solution: Utiliser PowerShell 32 bits
Heureusement, ce n'est pas sans solution, en effet, il suffit de se rabattre sur une version 32 bits de PowerShell pour pouvoir accéder librement au OleDB Provider 32 comme Jet Engine.
Et ça marche :-)
Gregory Stike aborde assez clairement ce sujet dans son article "How to Tell if PowerShell is 32-bit or 64-bit"
Pour résumer, il faut:
  • Démarrer un "command prompt" en mode Administrateur
  • Exécuter
    C:\Users\Stock>C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
  • Ne pas oublier de modifier l'exécution policy dans PowerShell si vous voulez exécuter un script
    Set-ExecutionPolicy Unrestricted
Lister les Provider OleDB
L'article "List of OLEDB providers on local or remote computer" présente un petit bout de code qui extrait la liste des OleDB provider enregistré dans la base de registre.
Si j'ai un jour du temps, j'en ferai un script PowerShell.
Un exemple concret
  # On 64 Bits OS, this must be executed with the PowerShell 32 bits
  #   C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
  
  # DB est stockée dans le répertoire c:\temp\Stock
  $ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\temp\stock;Extended Properties= dBASE IV"
  $conn = new-object System.Data.OleDb.OleDbConnection($ConnString)

  $conn.open()

  $cmd = new-object System.Data.OleDb.OleDbCommand("select * from FILE0030",$Conn)
  $da  = new-object System.Data.OleDb.OleDbDataAdapter($cmd)
  $dt  = new-object System.Data.DataTable

  $da.fill($dt)
    Write-Host "Contenu du DataTable"
  $dt 

  $conn.close() 


1 commentaire:

Anonyme a dit…

Salut,
parle nous plutot de ce que fait ce MVP ( SQLPSX), ce sera bien plus pertinent :
http://cmille19.wordpress.com/

Concernant ceci :
"The notes of a developer exploring platforms, languages and technologies."

Tu devrais reformuler :
"The notes of a developer exploring platforms, languages,technologies and the past."
Ceci dit cette dernière exploration a un intérêt limité...