4rocky4
Messages postés55Date d'inscriptionmercredi 1 novembre 2006StatutMembreDernière intervention16 avril 2009
-
3 mars 2009 à 14:49
4rocky4
Messages postés55Date d'inscriptionmercredi 1 novembre 2006StatutMembreDernière intervention16 avril 2009
-
11 mars 2009 à 11:38
Bonjour tout le monde,
Je dois migrer une base Sql Server 2005 vers oracle 11g.
J'ai obtenu un script de création des tables pour Oracle (fichier.sql) à l'aide de Dbdesigner fork mais ce script contient quelques erreurs :
- Remplacement des BIGINT par des NUMBER puis les DATETIME par des TIMESTAMP
- Création de triggers et séquences pour gérer l'auto incrément.
Je désire créer un projet sur SharpDevelop me permettant de parcourir "fichier.sql" pour y apporter les différentes modifications.
Mais celà est bien trop complet et compliqué pour moi.
Pourrais je trouver quelque chose de plus léger me permettant de répondre à mon attente ?
Je débute en SharpDevelop ainsi qu'en C mais pas dans le développement en général.
krimog
Messages postés1860Date d'inscriptionlundi 28 novembre 2005StatutMembreDernière intervention14 février 201549 3 mars 2009 à 16:01
Salut
Alors pour ton problème :
1) Tu ouvres le fichier et tu le lis
StreamReader reader = new StreamReader(File.OpenRead("fichier.sql"));
string texte = reader.ReadToEnd();
reader.Close();
2) Tu remplaces tes données
texte = texte.Replace("BIGINT", "NUMBER"); // Attention à la casse, il faut avoir la même que dans ton .sql de base
texte = texte.Replace("DATETIME", "TIMESTAMP");
3) Tu crées tes Triggers et tu les ajoutes à ta chaine
Là, c'est plus compliqué, car il faut que le programme "trouve" les champs ID.
Je n'ai pas le temps de faire le code pour ça, mais tu peux toujours essayer de regarder les méthodes SubString(), IndexOf(), ou encore les Regex
4) Tu enregistres ta chaine
StreamWriter writer = new StreamWriter("fichier.sql", false);
writer.Write(texte);
writer.Close();
4rocky4
Messages postés55Date d'inscriptionmercredi 1 novembre 2006StatutMembreDernière intervention16 avril 2009 3 mars 2009 à 16:59
Pouvez vous me dire si ma piste est possible ?
Alors dans mon script de création de table, il y a des tables qui contiennent de l'auto incrément et d'autre non.
Donc il faut créer une séquence et un trigger uniquement pour les tables contenant de l'auto incrément.
Le seul moyen de repérer ces tables dans le script est le mot IDENTITY (venant de Sql Server 2005)
CREATE TABLE T1_E (
ID_E INTEGER NOT NULL IDENTITY ,
NOM_E VARCHAR(32) NOT NULL ,
T1_E_LIB INTEGER ,
PRIMARY KEY(ID_E));
Faudrait-il faire une boucle qui permet de créer la séquence et le trigger pour toutes les tables contenant IDENTITY dans leur create ? Enfin est-ce possible surtout ... ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
krimog
Messages postés1860Date d'inscriptionlundi 28 novembre 2005StatutMembreDernière intervention14 février 201549 3 mars 2009 à 17:27
Grosso-modo, il faut choper POUR CHAQUE "Identity"
- Le nom de la table
- Le nom du champ
Et c'est là qu'est la difficulté.
En gros, voici comment je vois les choses par exemple pour trouver le nom de la table (attention, c'est certainement pas la manière la plus efficace).
int index = 0;
int indexId = 0;
//puis, tant qu'il y a "IDENTITY"
indexId = texte.IndexOf("IDENTITY");
while(texte.IndexOf("CREATE TABLE", index) < indexId)
{
index=IndexOf("CREATE TABLE", index);
}
// Donc là on a l'index du CREATE TABLE précédant un IDENTITY
Et donc là tu te déplaces jusqu'à la première lettre après CREATE TABLE, et jusqu'à l'espace ou la parenthèse suivante. Ainsi, tu as le nom de la table, et donc tu peux commencer à préparer ta requete pour créer ton trigger. Attention, le nom peut avoir des guillemets s'il contient un espace.
Tu fais ensuite un truc semblable pour le nom du champ et tu peux créer ton trigger
Enfin, tu passes au IDENTITY suivant.
Je crois que c'est beaucoup plus simple avec des Regex (expressions régulières), mais je ne maîtrise pas du tout. Si tu as un peu de temps, je te conseille quand même de te pancher dessus.
4rocky4
Messages postés55Date d'inscriptionmercredi 1 novembre 2006StatutMembreDernière intervention16 avril 2009 3 mars 2009 à 17:31
Pour faciliter cela, je pense qu'il faudrait créer un fichier par create puis de traiter ces fichiers un par un.
Pour les isoler il faudrait utiliser "create" et ";" mais une fois cela effectué je ne vois pas comment isoler les champs.
J'suis complètement perdu ou mon raisonnement est faisable ?
4rocky4
Messages postés55Date d'inscriptionmercredi 1 novembre 2006StatutMembreDernière intervention16 avril 2009 4 mars 2009 à 15:35
Bon ça va mieux pour les regex, j'ai réussi à faire ce que je voulais.
Par contre je ne suis pas sûr que votre méthode marche vraiment :
int index = 0;
int indexId = 0;
//puis, tant qu'il y a "IDENTITY"
indexId = texte.IndexOf("IDENTITY");
while(texte.IndexOf("CREATE TABLE", index) < indexId)
{
index=texte.IndexOf("CREATE TABLE", index);
}
// Donc là on a l'index du CREATE TABLE précédant un IDENTITY
J'ai rajouter "texte" qui est en rouge car à mon avis c'est un oubli.
Sinon quand j'exécute le code en pas à pas, "index" à l'intérieur de la boucle reste à 0 ...
krimog
Messages postés1860Date d'inscriptionlundi 28 novembre 2005StatutMembreDernière intervention14 février 201549 4 mars 2009 à 16:08
Salut.
Alors effectivement, j'avais bien oublié le texte. là où tu l'as mis en rouge.
Pour mon code, il y a effectivement une erreur : index doit être initialisé à -1 et il faut remplacer les 2 ("CREATE TABLE", index) par ("CREATE TABLE", index + 1), sinon il reste sur la boucle de la première occurence.
En revanche, mon code est très brouillon. Il faut par exemple vérifier lors des IndexOf qu'il trouve quelque chose.
PS : "pas sûr que votre méthode marche vraiment" => Pfiou, j'ai pris 20-30 ans d'un coup ^^ J'ai réellement pas l'habitude qu'on me vouvoie.