Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 15/09/2011, 16h28   #1
Membre confirmé
 
Avatar de awalter1
 
Inscription : août 2004
Messages : 665
Détails du profil
Informations forums :
Inscription : août 2004
Messages : 665
Points : 232
Points : 232
Par défaut Mise à jour conditionnelle d'une base

Bonjour,
Je fais un script sql d'upgrade pour modifier des tables. Je veux pouvoir appliquer ce script sur des bases qui ont ou qui n'ont pas déjà été upgradées. Il me faut alors pouvoir tester si ma table est dans l'ancien modèle ou le nouveau.
Des qu'une table est modifiée, je la renomme en old_table et la recrée avec la nouvelle definition puis la remplit à partir de old_table (cette façon de faire est éprouvée depuis longtemps).
Ca devrait ressembler à ça :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DECLARE
   modif number;
BEGIN
SELECT data_length INTO modif FROM user_tab_columns WHERE table_name='CONTROL' AND column_name='ERGO_POSITION';
IF modif < 10 THEN
-- REM l'upgrade de la table est nécessaire
   execute droptable('OLD_CONTROL')
   execute renametable('CONTROL')
   CREATE TABLE CONTROL (
      ARCHITECTURE VARCHAR2(20) NOT NULL,
      ERGO_POSITION VARCHAR2(10));
   DECLARE
      tablexist number;
   BEGIN
      SELECT count(*) INTO tableexist FROM user_tables WHERE table_name='OLD_CONTROL';
      IF tableexist > 0 THEN
         execute immediate
            'INSERT INTO CONTROL (ARCHITECTURE,ERGO_POSITION) SELECT ARCHITECTURE,ERGO_POSITION from OLD_CONTROL';
      END IF;
   END;
END IF;
END;
/
Cela ne marche pas car je pense que l'imbrication de la structure 'declare begin end' dans une autre structure 'declare begin end' pose problème. Comment le résoudre ?
Merci de votre aide
awalter1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2011, 21h02   #2
Membre éprouvé
 
Avatar de xdescamp
 
Homme Xavier Descamps
Inscription : octobre 2008
Messages : 297
Détails du profil
Informations personnelles :
Nom : Homme Xavier Descamps
Âge : 36
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2008
Messages : 297
Points : 422
Points : 422
Envoyer un message via Skype™ à xdescamp
Bonjour,
Citation:
Envoyé par awalter1 Voir le message
Cela ne marche pas ...
Un message d'erreur pourrait nous aider.

Ceci dit, ce qui ne peut pas fonctionner est l'instraction CREATE TABLE au milieu d'un bloc PL/SQL : il s'agit d'une instruction DDL alors que seuls les ordres DML sont autorisés en PL/SQL. L'astuce consiste à "cacher" cet ordre DDL dans un EXECUTE IMMEDIATE :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DECLARE
   modif number;
BEGIN
SELECT data_length INTO modif FROM user_tab_columns WHERE table_name='CONTROL' AND column_name='ERGO_POSITION';
IF modif < 10 THEN
-- REM l'upgrade de la table est nécessaire
   execute droptable('OLD_CONTROL')
   execute renametable('CONTROL')
   EXECUTE IMMEDIATE 'CREATE TABLE CONTROL (
      ARCHITECTURE VARCHAR2(20) NOT NULL,
      ERGO_POSITION VARCHAR2(10))';
   DECLARE
      tablexist number;
   BEGIN
      SELECT count(*) INTO tableexist FROM user_tables WHERE table_name='OLD_CONTROL';
      IF tableexist > 0 THEN
         execute immediate
            'INSERT INTO CONTROL (ARCHITECTURE,ERGO_POSITION) SELECT ARCHITECTURE,ERGO_POSITION from OLD_CONTROL';
      END IF;
   END;
END IF;
END;
/
xdescamp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/09/2011, 10h48   #3
Membre confirmé
 
Avatar de awalter1
 
Inscription : août 2004
Messages : 665
Détails du profil
Informations forums :
Inscription : août 2004
Messages : 665
Points : 232
Points : 232
Mais oui, c'est tout à fait cela : encapsuler mon ordre dans un execute immediate.
Merci beaucoup
awalter1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/09/2011, 11h09   #4
Membre confirmé
 
Avatar de awalter1
 
Inscription : août 2004
Messages : 665
Détails du profil
Informations forums :
Inscription : août 2004
Messages : 665
Points : 232
Points : 232
J'ai testé le 'CREATE' encapsulé dans le 'execute immediate' et c'est bon. Par contre le 'execute droptable('OLD_CONTROL')' n'est pas reconnu :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SQL> @testif.sql
execute droptable ('OLD_CONTROL')
        *
ERROR at line 6:
ORA-06550: line 6, COLUMN 9:
PLS-00103: Encountered the symbol "DROPTABLE" when expecting one of the
following:
:= . ( @ % ; immediate
The symbol ":=" was substituted FOR "DROPTABLE" TO continue.
ORA-06550: line 7, COLUMN 1:
PLS-00103: Encountered the symbol "EXECUTE" when expecting one of the
following:
. ( * % & = - + ; < / > at IN IS mod remainder NOT rem
<an exponent (**)> <> OR != OR ~= >= <= <> AND OR LIKE LIKE2_
LIKE4_ LIKEC_ BETWEEN || multis
Je redonne mon script :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
DECLARE
   modif number;
BEGIN
SELECT DATA_LENGTH INTO modif FROM user_tab_columns WHERE table_name='CONTROL' AND column_name='ERGO_POSITION';
IF modif < 11 THEN
execute droptable ('OLD_CONTROL')
execute immediate 
'CREATE TABLE TEST2 (ARCHITECTURE_NAME VARCHAR2(20) NOT NULL)';
DECLARE
   tableexist number;
BEGIN
SELECT count(*) INTO tableexist FROM user_tables WHERE table_name='CONTROL';
IF tableexist > 0 THEN
   execute immediate 'INSERT INTO OPS$OPE.TEST (ARCHITECTURE_NAME) SELECT simulation_name FROM   OPS$OPE.simul';
END IF;
END;
END IF;
END;
/
awalter1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h39.


 
 
 
 
Partenaires

Hébergement Web