Précédent   Forum des professionnels en informatique > Bases de données > Sybase
Sybase Forum sur la base de données Sybase. Avant de poster -> F.A.Q Sybase, Tutoriels Sybase
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 19/07/2006, 16h13   #1
Membre du Club
 
Inscription : octobre 2005
Messages : 79
Détails du profil
Informations personnelles :
Âge : 32

Informations forums :
Inscription : octobre 2005
Messages : 79
Points : 46
Points : 46
Par défaut [Sybase ASE 12.5.3] Gestion d'erreur avec @@error

Bonjour,

En premier, il y a les scripts puis mes questions suivent, merci.

script_01.sql

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
IF object_id('a') IS NOT NULL
   begin
      DROP TABLE a
   end
go
 
CREATE TABLE a (
a int NULL
)
go
 
INSERT INTO a (a) VALUES (1)
go
 
-- Début de transaction
 
begin tran
 
   INSERT INTO a (a) VALUES (3)
   -- Génère une erreur car la table n'existe pas
   INSERT INTO b (b) VALUES (2)
   SELECT @@error
   IF @@error <> 0
      begin
        rollback tran
        print "erreur"
        RETURN
      end
 
commit tran
go
 
SELECT * FROM a
go
 
IF object_id('a') IS NOT NULL
   begin
      DROP TABLE a
   end
go
script_02.sql

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
IF object_id('a') IS NOT NULL
   begin
      DROP TABLE a
   end
go
 
CREATE TABLE a (
a int NULL
)
go
 
INSERT INTO a (a) VALUES (1)
go
 
-- Début de transaction
 
begin tran
 
   INSERT INTO a (a) VALUES (3)
   -- Génère une erreur car la table n'existe pas
   INSERT INTO b (b) VALUES (2)
   SELECT @@error
   go
 
   IF @@error <> 0
      begin
        rollback tran
        print "erreur"
        RETURN
      end
 
commit tran
go
 
SELECT * FROM a
go
 
IF object_id('a') IS NOT NULL
   begin
      DROP TABLE a
   end
go
script_03.sql

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
IF object_id('a') IS NOT NULL
   begin
      DROP TABLE a
   end
go
 
CREATE TABLE a (
a int NULL
)
go
 
INSERT INTO a (a) VALUES (1)
go
 
-- Début de transaction
 
begin tran
 
   INSERT INTO a (a) VALUES (3)
   -- Génère une erreur car la table n'existe pas
   INSERT INTO b (b) VALUES (2)
 
   IF @@error <> 0
      begin
        rollback tran
        print "erreur"
        RETURN
      end
 
commit tran
go
 
SELECT * FROM a
go
 
IF object_id('a') IS NOT NULL
   begin
      DROP TABLE a
   end
go

Lorsque j'exécute ces scripts là avec isql j'obtiens :


Code :
1
2
3
4
5
6
7
8
9
10
11
 
(1 row affected)
Msg 208, Level 16, State 1:
Server 'MUTUDEV', Line 8:
b NOT found. Specify owner.objectname OR USE sp_help TO CHECK whether the object
EXISTS (sp_help may produce lots of output).
 a           
 ----------- 
           1 
 
(1 row affected)
Je constate qu'on sort du premier batch juste après "insert into b (b) values (2)".

Puis on reprend au deuxième batch.

Faut il en conclure que pour ce type d'erreur la gestion d'erreur n'y fait rien ?
Pourquoi ?

Maintenant la même opération avec sqladv :

script_01.sql

Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
(1 row affected)
Server Message:  Number  208, Severity  16
Server 'MUTUDEV', Line 7:
b NOT found. Specify owner.objectname OR USE sp_help TO CHECK whether the object EXISTS (sp_help may produce lots of output). 
(1 row affected)
 
Resultset :
 
a           
----------- 
          1
script_02.sql

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
(1 row affected)
Server Message:  Number  208, Severity  16
Server 'MUTUDEV', Line 7:
b NOT found. Specify owner.objectname OR USE sp_help TO CHECK whether the object EXISTS (sp_help may produce lots of output). 
erreur
(1 row affected)
 
Resultset :
 
a           
----------- 
          1
script_03.sql

Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
(1 row affected)
Server Message:  Number  208, Severity  16
Server 'MUTUDEV', Line 7:
b NOT found. Specify owner.objectname OR USE sp_help TO CHECK whether the object EXISTS (sp_help may produce lots of output). 
(1 row affected)
 
Resultset :
 
a           
----------- 
          1
Je remarque que la gestion d'erreur marche car il a bien fait le print "erreur".

Pourquoi la gestion d'erreur fonctionne sur le script_02.sql ?


Je tiens à préciser que le discours tenu par les formateurs sybase concernant la gestion d'erreurs est le suivant :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
/*
Gestion d'erreur lors de mises à jour
*/
 
IF conditions
   begin
 
      declare @err int, @rows int
 
      begin tran
 
      print "#@# Mise à jour de la table ..., champ ..."
 
      -- Instruction DML
 
      SELECT @err = @@error, @rows = @@rowcount
 
      IF @err <> 0
         begin
            rollback tran
            raiserror 30001, "table_name", "base_name"
            RETURN
         end
 
      commit tran
 
      print "Nombre de mises à jour : %1!." , @rows
 
   end
else
   begin
      print "Pas de mise à jour dans la table ..."
   end
go
Comment être sûr de sa gestion d'erreurs ?

Pour information :

1> select @@version
2> go
-----------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
----------------
Adaptive Server Enterprise/12.5.3/EBF 13197 ESD#6/P/Sun_svr4/OS 5.8/ase1253/1945/64-bit/FBO/Fri Jan 20 09:46:56 2006
lsone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/07/2006, 19h29   #2
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
Pour le premier script le comportement est normal.

Dans isql chaque batch est indépendant, et une erreur dans un batch n'affecte pas l'exécution des batchs suivants. De plus, une erreur de ce type (object does not exist) est flaguée au moment de la compilation et non pas au moment de l'exécution. Cela est la raison pour laquelle ce genre de code ne marche pas:

Code :
1
2
3
4
5
6
7
 
IF object_id('foo')
    begin
        SELECT ... FROM foo
    end
else
    print "La table foo n'existe pas"
On aura la même erreur (table foo does not exist) même si on se dit que le select ne devrait pas être exécuté en raison de la clause IF.

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/07/2006, 22h28   #3
Membre du Club
 
Inscription : octobre 2005
Messages : 79
Détails du profil
Informations personnelles :
Âge : 32

Informations forums :
Inscription : octobre 2005
Messages : 79
Points : 46
Points : 46
Citation:
Envoyé par mpeppler

Pour le premier script le comportement est normal.
Dans isql chaque batch est indépendant, et une erreur dans un batch n'affecte pas l'exécution des batchs suivants. De plus, une erreur de ce type (object does not exist) est flaguée au moment de la compilation et non pas au moment de l'exécution. Cela est la raison pour laquelle ce genre de code ne marche pas:

Code :
1
2
3
4
5
6
7
 
IF object_id('foo')
    begin
        SELECT ... FROM foo
    end
else
    print "La table foo n'existe pas"
On aura la même erreur (table foo does not exist) même si on se dit que le select ne devrait pas être exécuté en raison de la clause IF.

Michael
Merci.

En fait, si je comprends bien, le moteur compile puis exécute, normal !

Donc dans mon cas, la compilation ne marche pas, il écrit l'erreur, mais n'affecte pas au sein même du batch @@error puis passe au batch suivant.

D'ailleurs on le voit bien si on exécute ces deux batch :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
IF object_id('a') IS NOT NULL
   begin
      DROP TABLE a
   end
 
CREATE TABLE a (
a int NULL
)
 
INSERT INTO a (a) VALUES (1)
 
-- Début de transaction
 
begin tran
 
   INSERT INTO a (a) VALUES (3)
   -- Génère une erreur car la table n'existe pas
   INSERT INTO b (b) VALUES (2)
 
   IF @@error <> 0
      begin
        rollback tran
        print "erreur"
        RETURN
      end
 
commit tran
go
 
SELECT @@error
go
Le resultset :

Code :
1
2
3
4
5
6
7
8
9
10
 
 
Msg 208, Level 16, State 1:
Server 'ILLEGAL', Line 17:
b NOT found. Specify owner.objectname OR USE sp_help TO CHECK whether the object EXISTS (sp_help may produce lots of output).
 
 ----------- 
         208 
 
(1 row affected)
Pour quel genre d'erreur le code ci-dessous va gérer correctement l'erreur ?

Puisque pour les erreurs de syntaxe, d'objets non trouvé cela ne marche pas.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
 
/*
Gestion d'erreur lors de mises à jour
*/
 
declare @err int, @rows int
 
begin tran
 
   print "#@# Mise à jour de la table ..., champ ..."
 
   -- Instruction DML
 
   SELECT @err = @@error, @rows = @@rowcount
 
   IF @err <> 0
      begin
         rollback tran
         raiserror 30001, "table_name", "base_name"
         RETURN
      end
 
commit tran
print "Nombre de mises à jour : %1!." , @rows
go
Les erreurs de compilation, je comprends mais alors quelles erreurs peuvent passer à la compilation et planter à l'exécution ?

PS :
Le code de gestion d'erreurs est inspiré (voir plagié) de la documentation (édition 2002) fournie lors de la formation Transact SQL ASE 12.5, chapitre 15-38.
lsone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/07/2006, 15h24   #4
Membre du Club
 
Inscription : octobre 2005
Messages : 79
Détails du profil
Informations personnelles :
Âge : 32

Informations forums :
Inscription : octobre 2005
Messages : 79
Points : 46
Points : 46
Pas de réponses ?
lsone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/07/2006, 16h07   #5
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
Toutes les erreurs autres que des erreurs lors de la compilation - cad erreur de droits d'accès, de violation de clé primaire, etc, etc, etc...

Dans le cas d'une proc. stockée il pourrait aussi y avoir le problème où une table existe au moment où la proc est créée, mais où elle a été droppée entre temps.

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/07/2006, 22h25   #6
Membre du Club
 
Inscription : octobre 2005
Messages : 79
Détails du profil
Informations personnelles :
Âge : 32

Informations forums :
Inscription : octobre 2005
Messages : 79
Points : 46
Points : 46
Merci !
lsone 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 11h12.


 
 
 
 
Partenaires

Hébergement Web