Adaptation de script

Résolu
4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 avril 2009 - 3 mars 2009 à 14:49
4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 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.

J'ai trouvé cette solution :
http://www.csharpfr.com/codes/REMPLACEMENT-AUTOMATISE-CHAINES-CARACTERES_34898.aspx

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.

Merci

11 réponses

4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 avril 2009
4 mars 2009 à 17:04
Je vouvoie toujours les personnes qui ne m'ont pas dit que je pouvais les tutoyer :)

Pour le traitement, je suis parti encore dans les regex, on va voir XD
3
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
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();








Krimog :
while (!succeed = try()) ;
0
4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 avril 2009
3 mars 2009 à 16:42
Merci bien pour cette réponse très claire !
J'ai très bien compris et j'ai pu l'utiliser comme je veux :)

Je regarde de suite pour les triggers
0
4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 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 ... ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
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.

Krimog :
while (!succeed = try()) ;
0
4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 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 ?
0
4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 avril 2009
3 mars 2009 à 17:34
Merci beaucoup pour ta réponse, je vais regarder ça
0
4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 avril 2009
4 mars 2009 à 10:37
Je me suis lancé dans l'expression régulière et effectivement, c'est la meilleur solution je pense pour récupérer le nom de la table et du champ.

Mais débutant dans les regex, je n'y arrive pas :s
0
4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 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 ...

je bloque ici
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
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.

Krimog :
while (!succeed = try()) ;
0
4rocky4 Messages postés 55 Date d'inscription mercredi 1 novembre 2006 Statut Membre Dernière intervention 16 avril 2009
11 mars 2009 à 11:38
Les expressions régulières étaient une bonne solution ! Merci
0
Rejoignez-nous