Kroc - 18 Octobre 2006 : Avec le script ci-dessous, vous pourrez importer une table Oracle dans une table SQLite.
La version 1.x a été élaborée et testée avec :
################################################################################ # # Convertisseur de table Oracle vers SQLite # # Copyright © 2006 - David Zolli # # Ce script est sous licence NOL : http://wfr.tcl.tk/NOL # ################################################################################ # # Historique des révisions : # # 18 Octobre 2006 : Version 1.0 # 19 Octobre 2006 : Version 1.1 - Ajout du support des types # ################################################################################ # # Utilisation : # # updateOracle Matable primary_key fichierSQL oraUSER oraPWD oraSID # # Avec : # # - Matable = le nom de la table à transférer # - primary_key = le nom de la clé selon laquelle la table est indexée # - fichierSQL = le nom du fichier de base de données SQLite # - oraUSER = le nom d'utilisateur Oracle # - oraPWD = le mot de passe Oracle pour oraUSER # - oraSID = le SID Oracle auquel se connecter # ################################################################################ # à adapter selon votre propre installation d'Oracle instant client : if {![info exists ::env(ORACLE_HOME)} { set ::env(ORACLE_HOME) [file normalize ~/Oracle_8.1.7.1_Client] } # Ne rien modifier en dessous de cette ligne. package require -exact sqlite3 3.2.8 package require Oratcl proc updateOracle {Matable primary_key fichierSQL oraUSER oraPWD oraSID} { # Connexion au serveur : if {![catch "oralogon ${oraUSER}/${oraPWD}@${oraSID}" lda] && ![catch "oraopen $lda" sth]} { puts "Connecté.." # Initialisation de la table SQLite si elle n'existe pas déjà : if {![file exists $fichierSQL]} { # Structure de la table Oracle : set oracle_desc [oradesc $lda $Matable] initDB $Matable $fichierSQL $oracle_desc $primary_key } # Récupération de la structure de la table SQLite : set listCols [getSTy $Matable $fichierSQL] # Récupération de la table Oracle : oraparse $sth "SELECT * FROM $Matable ORDER BY $primary_key" oraexec $sth # Traitement : set nblignes 0 set fout [open ./tmp.csv w] while {[orafetch $sth -dataarray AR]==0} { incr nblignes # Conversion des données selon le type attendu : set values {} foreach col $listCols { if {![info exists AR($col)]} {set AR($col) NULL} switch -exact [lindex $::STy($col) 0] { char { # On ne conserve que la longueur définie dans la structure : lappend values [string range $AR($col) 0 [lindex $::STy($col) 1]] } varchar - real - tinytext { # On enlève les espaces inutiles : lappend values [string trim $AR($col)] } timestamp { # Conversion en Epoch : if {![catch "clock scan $AR($col)" tstamp]} { lappend values $tstamp } else { lappend values [clock second] } } } } puts $fout [join $values \t] # Affichage / log : if {![expr {$nblignes%50}]} { puts stdout ".\t$nblignes" ; flush stdout } elseif {![expr {$nblignes%10}]} { puts -nonewline stdout ". " ; flush stdout } else { puts -nonewline stdout . ; flush stdout } } # Déconnexion : oraclose $sth oralogoff $lda close $fout if {$nblignes} { puts stdout "\n$nblignes fiches récupérées." updateSQLite $Matable $fichierSQL } else { puts stdout "Aucune nouvelle fiche." } } else { # Echec : puts stdout "La connexion a échouée." } } # Création d'une nouvelle base de données SQLite si elle n'existe pas encore : proc initDB {Matable fichierSQL oracle_desc primary_key} { # Initialisation de la base SQLite : sqlite3 DB $fichierSQL # Structure de la table SQLite à partir de la structure Oracle : set struct {} foreach l $oracle_desc { foreach "nom taille type A B C" $l { switch -exact $type { CHAR {set TY char ; set TA "($taille)"} VARCHAR2 {set TY varchar ; set TA "($taille)"} NUMBER {set TY real ; set TA ""} DATE {set TY timestamp ; set TA ""} default {set TY tinytext ; set TA ""} } if {$nom eq $primary_key} { lappend struct "$nom $TY $TA PRIMARY KEY" } else { lappend struct "$nom $TY $TA" } } } eval DB eval [list "CREATE TABLE [set Matable]([join $struct ", "])"] DB close puts "Table $Matable créée à partir de la structure suivante :" puts $oracle_desc } # Récupération de la structure des types d'une table (dans un tableau global) : proc getSTy {Matable fichierSQL} { unset -nocomplain ::STy set ordre {} # Récupération de la structure de la table SQLite : sqlite3 DB $fichierSQL set R [DB eval [list SELECT sql FROM SQLITE_MASTER WHERE name='$Matable']] DB close set R [string range $R [expr {[string first ( $R]+1}] [expr {[string last ) $R]-1}]] foreach v [split $R ,] { foreach "nom type taille P K" $v { lappend ordre $nom set ::STy($nom) [list $type [string map {( "" ) ""} $taille]] } } return $ordre } # Met à jour une table SQLite avec un CSV : proc updateSQLite {Matable fichierSQL} { set rec 0 if {[file exists $fichierSQL] && [file exists ./tmp.csv]} { # Mise à jour avec "copy" (ne marche qu'avec SQlite 3.2.8) : sqlite3 DB $fichierSQL set rec [DB copy REPLACE $Matable ./tmp.csv "\t" "NULL"] DB close # Le fichier a été traité, on peut l'effacer : file delete -force ./tmp.csv } puts "$rec fiches ajoutées à la base SQLite." return }