IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Sybase Discussion :

[ASE] Erreur 941 - Illegal database context operation


Sujet :

Sybase

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut [ASE] Erreur 941 - Illegal database context operation
    Bonjour à tous.

    Je m'essaye à écrire une proc stockée sur Sybase ASE 11.9 (je sais, ce n'est
    plus maintenu !!)
    La voici. C'est une proc qui renvoie des valeurs qui servent pour les clés
    primaires numériques

    Lorsque je l'execute via transact SQL je suis déconnecté et j'ai une
    méchante erreur dans le log de Sybase: 941 - Illegal database context
    operation

    Comment faire pour la résoudre?
    J'ai essayé la solution proposé ici mais rien à faire.
    Merci de votre aide.

    Abel

    Erreur obtenue (extrait log du serveur)
    --------------------------------------------
    00:00000:00010:2006/07/12 15:27:10.87 server Error: 941, Severity: 20, State: 1
    00:00000:00010:2006/07/12 15:27:10.87 server Illegal database context operation.
    00:00000:00010:2006/07/12 15:27:10.87 kernel ************************************
    00:00000:00010:2006/07/12 15:27:10.87 kernel SQL causing error : DECLARE @i decimal
    exec stpr_get_counter 'NAME',@i
    SELECT @i
    00:00000:00010:2006/07/12 15:27:10.87 kernel ************************************
    00:00000:00010:2006/07/12 15:27:10.89 server SQL Text: DECLARE @i decimal
    exec stpr_get_counter 'NAME',@i
    SELECT @i
    00:00000:00010:2006/07/12 15:27:10.89 kernel curdb = 5 pstat = 0x10000 lasterror = 941
    00:00000:00010:2006/07/12 15:27:10.89 kernel preverror = 0 transtate = 0
    00:00000:00010:2006/07/12 15:27:10.89 kernel curcmd = 224 program = SQL_Advantage
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x8a2977 os_get_cur_stk_desc+ 0x57 (0x13ff04c, 0x1d001d, 0x13ff04c, 0x0)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x8a2977 os_get_cur_stk_desc+ 0x57 (0x13ff04c, 0x13ff5a0, 0x270f, 0x2)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x883514 pcstkwalk+ 0x224 (0x1d001d, 0x2, 0x270f, 0x0)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x8830ae ucstkgentrace+ 0x1ce (0x0, 0x1, 0x14, 0x0)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x862864 ucbacktrace+ 0x84 (0x0, 0xffffffff, 0x13ff964, 0x4527a8)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x405fe6 terminate_process+ 0x566 (0x13ff9c4, 0x639a02, 0x9, 0x29)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x4527ea close_network+ 0x1a (0x9, 0x29, 0x14, 0x1)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x4527a8 hdl_default+ 0x48 (0x9, 0x29, 0x14, 0x1)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x639a02 s_handle+ 0x162 (0x9, 0x29, 0x14, 0x1)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x452413 ex_raise+ 0x193 (0xffffffff, 0x202d2594, 0x20010060, 0x0)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x47597c closedb+ 0x2ac (0x208192ac, 0x20819324, 0x0, 0x0)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x65a328 execproc+ 0x828 (0x202d2594, 0x81a, 0x2081edec, 0x0)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x65467a s_execute+ 0x213a (0x2080c800, 0x202d2594, 0x20010060, 0x0)
    00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x6398a0 s_handle installed by the following function:-]
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x63678f sequencer+ 0x15f (0x2081ed74, 0x2081edec, 0x0, 0x0)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x659d8f execproc+ 0x28f (0x21, 0x202d2594, 0x202d2594, 0x20288e28)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x65467a s_execute+ 0x213a (0x2082d800, 0x21, 0x202d97d1, 0x202d2594)
    00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x6398a0 s_handle installed by the following function:-]
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x63678f sequencer+ 0x15f (0x0, 0x20014b38, 0x1c001c, 0x20013830)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x436d31 tdsrecv_language+ 0xc1 (0x3, 0x4000, 0x20014b38, 0x1c001c)
    00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x452660 hdl_backout installed by the following function:-]
    00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x5c0c40 ut_handle installed by the following function:-]
    00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x5c0c40 ut_handle installed by the following function:-]
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x40dc1c conn_hdlr+ 0xb5c (0x20014b38, 0x20013830, 0x1c001c, 0x20014b38)
    00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x89c1c6 kpntwrapper+ 0x96 (0x89c130, 0x20014b38, 0x0, 0x0)
    00:00000:00010:2006/07/12 15:27:10.96 kernel pc: 0x7c80b50b kernel32.dll (0x661b4e, 0x20821800, 0xff, 0x2)
    00:00000:00010:2006/07/12 15:27:10.96 kernel end of stack trace, spid 10, kpid 1900573, suid 11
    ------------------------
    Transact sql pour executer la proc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ----------
    DECLARE @i decimal
    exec stpr_get_counter 'NAME',@i
    SELECT @i
    ----------
    Code de la proc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    ------------------------------------------------
    CREATE Procedure stpr_get_counter
    @countername VARCHAR(128),
    @countervalue DECIMAL = NULL OUTPUT
    AS
     
     DECLARE @errmsg VARCHAR(255)
     DECLARE @strQuery VARCHAR(255)
     DECLARE @ok INT
      DECLARE @nextvalue DECIMAL
     
      SELECT @ok = 0
     SELECT @nextvalue = -1
     
     SET NOCOUNT ON
     
    -- Highest transaction level. Only one connection can enter this at the same 
    time
     SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
     BEGIN TRAN GET_COUNTER
     
     SELECT @ok = COUNT(*) FROM ref_counters WHERE cnt_name = @countername
     IF @@ERROR > 0
     BEGIN
      SELECT @errmsg = 'Failed on query SELECT COUNT(*) FROM ref_counters'
      GOTO ERROR_HANDLER
     END
    -- Insert countername entry if necessary
     IF @ok = 0
     BEGIN
      SELECT @strQuery = 'INSERT INTO ref_counters (cnt_name, cnt_lastvalue) 
    VALUES (''' +  @countername + ''', 0)'
      EXEC @strQuery
      IF @@ERROR > 0
      BEGIN
       SELECT @errmsg = 'Failed on statement INSERT INTO ref_counters'
       GOTO ERROR_HANDLER
      END
     END
     
    -- Getting next counter value
     SELECT @nextvalue = cnt_lastvalue + 1 FROM ref_counters WHERE cnt_name = 
    @countername
     IF @@ERROR > 0
     BEGIN
      SELECT @errmsg = 'Failed on query SELECT cnt_lastvalue+1 FROM 
    ref_counters'
      GOTO ERROR_HANDLER
     END
    -- Update last value in counters table
     UPDATE ref_counters SET cnt_lastvalue = @nextvalue WHERE cnt_name = 
    @countername
     IF @@ERROR > 0
     BEGIN
      SELECT @errmsg = 'Failed on statement UPDATE ref_counters'
      GOTO ERROR_HANDLER
     END
    -- Return counter
     SELECT @countervalue = @nextvalue
     
     SELECT @countervalue
     
    -- Commit transaction
     COMMIT TRAN GET_COUNTER
     
     SET NOCOUNT OFF
     RETURN 0
     
    ERROR_HANDLER:
     ROLLBACK TRAN GET_COUNTER
     SET NOCOUNT OFF
     RAISERROR @@ERROR
     PRINT @errmsg
     RETURN @@ERROR
     
    ------------------------------------------

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Par défaut
    Bonjour,

    Je viens de répondre sur les forums Sybase, mais je peux reposter ici...

    Le problème vient à priori du "execute immediate" qui n'est disponible qu'à partir de la version 12. De plus la syntaxe correcte serait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    EXEC (@sqlCommand)
    où les parenthèses sont obligatoire pour indiquer que @sqlCommand ne contient pas le nom d'une proc stockée ou d'une RPC.

    Michael

  3. #3
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut


    Si ça ne vous dérange pas on peut continuer ici?

    Citation Envoyé par sur le forum sybase j'ai répondu
    Merci de votre aide.

    J'ai traduit le code d'une proc stock SQL SERVER 2000 et avant il y avait
    les parenthèses.
    J'ai enlever les parenthèses car la proc ne fonctionnait pas avec (erreur
    script création)

    Savez vous quelles sont les alternatives à EXEC pour la 11.9 ?

    Merci

    Abel
    Edit : PS: Auriez vous quelques instants à consacrer à ceci ?

  4. #4
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut
    J'ai trouvé ça et apparement ça marche
    http://www.sypron.nl/dynsqlcis.html

    Merci

  5. #5
    Membre Expert

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Par défaut
    C'était exactement ce que j'allais suggérer...

    Michael

  6. #6
    Rédacteur/Modérateur

    Avatar de Fabien Celaia
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    4 228
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 4 228
    Billets dans le blog
    25
    Par défaut
    Citation Envoyé par abelman
    J'ai trouvé ça et apparement ça marche
    http://www.sypron.nl/dynsqlcis.html

    Merci
    Oui, c'est un grand classique que de boucler sur son propre serveur via CIS... par contre attention aux perfs...
    Sr DBA Oracle / MS-SQL / MySQL / Postgresql / SAP-Sybase / Informix / DB2

    N'oublie pas de consulter mes articles, mon blog, les cours et les FAQ SGBD

    Attention : pas de réponse technique par MP : pensez aux autres, passez par les forums !

  7. #7
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut
    Re, j'ai mis résolu trop vite.

    J'ai suivi à la lettre les indications du site sypron

    J'ai configuré mon serveur pour CIS avec les deux scripts et cela a fonctionné.

    Par contre quand j'éxecute ma proc, il me dit qu'il ne trouve pas la table ref_counters. (REquête INSERT INTO ref_counters .. dans ma proc plus haut)

    Qui existe bel et bien.

    J'ai fait quelques test et j'ai vu que ça marche quand je prefixe la table par le nom de la base de données.

    J'arrive à le faire pour le insert.

    Comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	SELECT @db=db_name() 
        	PRINT @db 
            SELECT @strQuery = 'INSERT INTO ' + @db + '..ref_counters (cnt_name, cnt_lastvalue) VALUES (''' +  @countername + ''', 0)'  
            PRINT @strQuery 
            EXEC sp_exec_dynsql @strQuery
    Mais comment faire pour ce genre de requête pour prefixer???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    --  Getting next counter value  
        SELECT @nextvalue = cnt_lastvalue + 1 FROM ref_counters WHERE cnt_name = @countername  
        IF @@ERROR > 0  
        BEGIN  
            SELECT @errmsg = 'Failed on query SELECT cnt_lastvalue+1 FROM ref_counters'  
            GOTO ERROR_HANDLER  
        END  
    --  Update last value in counters table  
        UPDATE ref_counters SET cnt_lastvalue = @nextvalue WHERE cnt_name = @countername
    Il faut utiliser les curseurs? Je ne sais pas les utiliser (pr l'instant). Vous connaissez des tutos dessus? ou bien avez vous d'autres suggestions?

    Merci

  8. #8
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut


    Merci de ne pas tenir compte de mon dernier message.
    Je vais prefixer le nom de la base en dur directement dans les requêtes car la proc est un objet d'une seule base ...

    @+

  9. #9
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut
    Re bonjour,

    Alors j'ai essayer d'utiliser ma nouvelle proc stock avec la gestion du Exec contourné avec les Remote IO. (Sybase 11.9.2)

    ça ne marche pas.

    Le code suivant bloque et je n'ai plus la main. (Je dois tuer l'application pour reprendre la main)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    declare @cpt decimal
    exec @cpt=stpr_get_counter 'compteurx'
    select @cpt
    Quand je regarde l'état du processus dans Sybase central, j'ai:
    ID=1
    Programme = SQL_Advantage
    Commande= EXECUTE
    Login=sa
    Etat = remote i/o

    Je n'ai rien dans les logs.

    Une idée? Devrais je avoir un service annexe Sybase qui tourne? Qu'est ce que c'est qu'un XP server par exemple? Dans mes logs j'ai toujours un 'XP Server is not running' lors de l'arrêt du serveur.

    JE remet le code de la proc stock ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    ------------------------------------------------
     CREATE Procedure stpr_get_counter  
    @countername VARCHAR(128),  
    @countervalue DECIMAL = NULL OUTPUT  
    AS  
     
        DECLARE @errmsg VARCHAR(255)  
        DECLARE @strQuery VARCHAR(255)  
        DECLARE @ok INT  
        DECLARE @nextvalue DECIMAL  
        DECLARE @dbname VARCHAR(50) 
     
        SELECT @ok = 0  
        SELECT @nextvalue = -1  
     
        SET NOCOUNT ON  
     
    --  Highest transaction level. Only one connection can enter this at the same time  
        SET TRANSACTION ISOLATION LEVEL SERIALIZABLE  
        BEGIN TRAN GET_COUNTER  
     
    --  Search for coutername entry in counter table  
        --SET @ok = 0  
        SELECT @ok = COUNT(*) FROM ref_counters WHERE cnt_name = @countername  
        IF @@ERROR > 0  
        BEGIN  
            SELECT @errmsg = 'Failed on query SELECT COUNT(*) FROM ref_counters'  
            GOTO ERROR_HANDLER  
        END  
    -- Insert countername entry if necessary  
        IF @ok = 0  
        BEGIN  
        		SELECT @dbname=db_name() 
        		PRINT @dbname 
            SELECT @strQuery = 'INSERT INTO ' + @dbname + '..ref_counters (cnt_name, cnt_lastvalue) VALUES (''' +  @countername + ''', 0)'  
            PRINT @strQuery 
            EXEC sp_exec_dynsql @strQuery  
            IF @@ERROR > 0  
            BEGIN  
                SELECT @errmsg = 'Failed on statement INSERT INTO ref_counters'  
                GOTO ERROR_HANDLER  
            END  
        END  
     
    --  Getting next counter value  
        SELECT @nextvalue = cnt_lastvalue + 1 FROM ref_counters WHERE cnt_name = @countername  
        IF @@ERROR > 0  
        BEGIN  
            SELECT @errmsg = 'Failed on query SELECT cnt_lastvalue+1 FROM ref_counters'  
            GOTO ERROR_HANDLER  
        END  
    --  Update last value in counters table  
        UPDATE ref_counters SET cnt_lastvalue = @nextvalue WHERE cnt_name = @countername  
        IF @@ERROR > 0  
        BEGIN  
            SELECT @errmsg = 'Failed on statement UPDATE ref_counters'  
            GOTO ERROR_HANDLER  
        END  
    --  Return counter  
        SELECT @countervalue = @nextvalue  
     
        SELECT @countervalue  
     
    --  Commit transaction  
        COMMIT TRAN GET_COUNTER  
     
        SET NOCOUNT OFF  
        RETURN @countervalue
     
    ERROR_HANDLER:  
        ROLLBACK TRAN GET_COUNTER  
        SET NOCOUNT OFF  
        PRINT @errmsg 
        --RAISERROR @@ERROR   
        RETURN @@ERROR

  10. #10
    Membre Expert

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Par défaut
    Le XP server permet d'exécuter une command OS ou du code C ad-hoc comme une proc stockée. Ce module n'est donc pas en cause ici.

    Je suspecte qu'il y a peut-être un problème de logique au niveau des transactions avec l'appel imbriqué de l'insert via sp_remote_sql. Il faut savoir que cet appel ne peut pas être fait dans le contexte de la transaction en cours, et si la requete qui est exécutée par sp_remote_sql doit accèder à une table qui est bloquée par la transaction démarrée dans la proc stpr_get_counter alors elle risque de tout bloquer.

    Pour vérifier il suffit d'ouvirir une connexion supplémentaire et de faire un sp_who. Si le process est bloqué en "lock sleep" alors cela confirmerait cette analyse.

    Michael

  11. #11
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut
    Effectivement c'est le cas.

    Quand j'enlève le niveau d'isolation maximum
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    ça fonctionne très bien.

    Le problème c'est que cette procedure sera très probablement sollicitée par plusieurs processus différents et de manière simultanée souhaitant obtenir la même valeur de compteur.

    Comment faire dans ce cas pour garantir l'intégrité du compteur retourné? (pas de doublons)

    Merci de votre aide en tout cas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Sunopsis V4 Sybase ASE : erreur JZ0P1
    Par n.roussaly dans le forum ODI (ex-Sunopsis)
    Réponses: 1
    Dernier message: 20/06/2007, 16h10
  2. Sybase ASE : erreur JZ0P1
    Par n.roussaly dans le forum Sybase
    Réponses: 11
    Dernier message: 20/06/2007, 16h06
  3. Message d'erreur "Repérage illegal"
    Par tiboo dans le forum Administration système
    Réponses: 3
    Dernier message: 18/04/2007, 20h33
  4. Réponses: 7
    Dernier message: 17/10/2006, 13h55
  5. Réponses: 4
    Dernier message: 17/01/2006, 18h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo