On utilisera ici la capacité de PhpMyAdmin à créer des tables MySQL par import d'un fichier texte... notre script se résumera donc à la production dudit fichier à l'aide du File System Object
Quelques remarques
Les lignes de commentaires débutent par # et sont donc ignorées
Pour éviter les problèmes dûs aux mots réservés par le langage SQL, on encadrera les noms de tables et de champs par deux AltGr-7 `nom` (pour Access c'est [nom])
Prévoir de supprimer une table du même nom si elle existe déjà : "DROP TABLE IF EXISTS `matable`;"
La propriété auto-incrément ne sera pas préservée dans la conversion
Conversion des types
C'est là qu'on commence à s'amuser..:o) Les solutions proposées ci-dessous ne sont que des exemples rapides qui peuvent très certainement être améliorés... si vous vous y collez, n'hésitez pas à me proposer les vôtres !
Type Access
Type MySQL
Remarques
byte
tinyint
de -128 à 127
smallint
smallint
de -32768 à 32767
integer
int
de -2147483648 à 2147483647
real
float
de 0 à ±3.402823466 E+38 (précision E-38)
number
double
de 0 à ±1.7976931348623157 E+308 (précision E-308)
money
float(15,4)
Le type money n'existe pas dans MySQL donc si l'on suit fidèlement la description du type Access...
boolean
char(1)
Arfff... le type booléen n'existe pas... on va donc utiliser un champ texte dans lequel on mettra "Y" (true) or "N" (false) - on aurait aussi pû mettre un tinyint avec 1 ou 0
date
datetime
Bon, là plusieurs solutions étaient possibles : DATETIME, DATE, TIMESTAMP à vous de voir... le format pour DATETIME est 'YYYY-MM-DD HH:MM:SS'... une conversion est donc nécessaire
text(xxx)
varchar(xxx)
Deux conversions sont à effectuer à cause des requêtes INSERT :
Les VbCrLf et autres chr(13) doivent devenir "\r\n"
Les ' doivent évidemment être interceptés "\'"
memo
longtext
Le script complet
access2mysql.asp
<% ' Export MSAccess >> MySQL
Set FSO = Server.CreateObject("Scripting.FileSystemObject")
BASE = "mabase" ' Adaptez votre chaîne de connexion ! basePath = server.mapPath("/htdocs") & "\..\database\" & BASE & ".mdb" TABLE = "matable" SQL = "SELECT * FROM [" & TABLE & "]" ' par exemple ' nom du fichier d'export (dans rep déprotégé !!!) fichier = server.mapPath("/data") & "\" & BASE & "_" & TABLE & ".txt"
' Connexion à la base Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & basePath
' Ouverture du recordset Set RS = Server.CreateObject("ADODB.Recordset") RS.open SQL,conn,3,3
' Destruction optionnelle de la table MySQLstr = MySQLstr & "DROP TABLE IF EXISTS `" & TABLE & "`;" & VbCrLf ' Création de la table MySQLstr = MySQLstr & "CREATE TABLE `" & TABLE & "` (" & VbCrLf ' Création des champs for each Champ in RS.fields temp = " `" & Champ.name & "` " select case Champ.type case 2 : ' Entier court MySQLstr = MySQLstr & temp & "smallint," & VbCrLf case 3 : ' Entier long MySQLstr = MySQLstr & temp & "int," & VbCrLf case 4 : ' Réel MySQLstr = MySQLstr & temp & "float," & VbCrLf case 5 : ' Réel long MySQLstr = MySQLstr & temp & "double," & VbCrLf case 6 : ' Monétaire MySQLstr = MySQLstr & temp & "float(15,4)," & VbCrLf case 11 : ' Booléen MySQLstr = MySQLstr & temp & "char(1)," & VbCrLf case 17 : ' Byte MySQLstr = MySQLstr & temp & "tinyint," & VbCrLf case 135 : ' Date/Time MySQLstr = MySQLstr & temp & "datetime," & VbCrLf case 200,202 : ' Texte MySQLstr = MySQLstr & temp & "varchar(" & Champ.definedsize & ")," & VbCrLf case 201,203 : ' Mémo MySQLstr = MySQLstr & temp & "longtext," & VbCrLf ' sinon non exporté... end select next ' Fin de la création de la table MySQLstr = left(MySQLstr,len(MySQLstr)-3) & VbCrLf & ") TYPE=MyISAM;" & VbCrLf & VbCrLf
' Fonctions de conversion
function n2t(n,w) ' Entier > chaine 000x ou 0x n2t = right("000" & cStr(n),w) end function
function txt2mys(txt) ' Caractères spéciaux pour INSERT dim temp if not isnull(txt) then temp = replace(txt,VbCrLf,"\r\n") temp = replace(temp,chr(13),"\r\n") txt2mys = replace(temp,"'","\'") end if end function
' Création des enregistrements while not RS.eof MySQLstr = MySQLstr & "INSERT INTO `" & TABLE & "` (" ' Les noms for each Champ in RS.fields select case Champ.type case 2,3,4,5,6,11,17,135,200,201,202,203 : MySQLstr = MySQLstr & "`" & Champ.name & "`," ' sinon non exporté... end select next ' Les valeurs MySQLstr = left(MySQLstr,len(MySQLstr)-1) & ") VALUES (" for each Champ in RS.fields select case Champ.type case 2,3,4,5,6,17 : ' Numériques MySQLstr = MySQLstr & Champ.value & "," case 11 : ' Booléen >> char(1) : "Y" ou "N" if(Champ.value) then MySQLstr = MySQLstr & "'Y'," _ else MySQLstr = MySQLstr & "'N'," case 135 : ' Date time >> YYYY-MM-DD HH:MM:SS MySQLstr = MySQLstr & "'" _ & n2t(year(Champ.value),4) & "-" _ & n2t(month(Champ.value),2) & "-" _ & n2t(day(Champ.value),2) & " " _ & n2t(hour(Champ.value),2) & ":" _ & n2t(minute(Champ.value),2) & ":" _ & n2t(second(Champ.value),2) & "'," case 200,201,202,203 : ' Texte >> nettoyage MySQLstr = MySQLstr & "'" & txt2mys(Champ.value) & "'," ' sinon non exporté... end select next MySQLstr = left(MySQLstr,len(MySQLstr)-1) & ");" & VbCrLf
' Enregistrement suivant RS.movenext wend
' Fermeture de la connexion RS.close : conn.close
' Ecriture du fichier set inF = FSO.openTextFile(Fichier,2,true) inF.writeLine(MySQLstr) inF.close