Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour à tous,
Je voudrais vous soumettre un problème que j'ai avec une application PB.
C'est une application PB 11.2 build 8407 classic. Il y a une connection vers la database Oracle 10g.
Dans un écran classique, il y a une datawindow basée sur une procédure stockée dans un package Oracle. Jusque là tout va bien.
A l'ouverture de l'écran, le retrieve est fait sur la dw et le resultat est affiché.
Sur l'écran principal mdi de l'application, il y a un timer qui va aussi faire appel à une procédure stockée.
Tout va encore bien là aussi.
Quand le timer s'exécute, et que je me trouve sur l'écran en question, il y a ce message qui pop
Si je clique sur le bouton Abort, il y a un autre message d'erreur.
J'avoue que je suis completement perdu.
Je ne comprend pas d'oû vient cette erreur.
Il n'y a pas de code C++ dans l'application PB.
Il semblerait que le problème ne survienne qu'avec l'exécutable et pas à partir de Powerbuilder.
Est-ce que quelqu'un aurai-il une idée de ce que je devrais regarder ?
Merci d'avance à tous pour votre aide.
Benoit
Hors ligne
Je commencerai par regarder la procédure stockée appelée par le timer:
- A-t'elle des paramètres en IN/OUT
- A-t'elle des paramètres de types particuliers (BLOB,CLOB, arrays, etc...)
- Méthode d'appel: Declare Excecute Fetch ou RPCFUNC?
Bref, des exemples de code PL-SQL ET PB seraient les bienvenus
Hors ligne
Thorben a écrit:
Je ne comprend pas d'oû vient cette erreur.
Il n'y a pas de code C++ dans l'application PB.
Un bug a provoqué une faute d'assertion dans un module de PB (qui lui est programmé en c++).
Aparté C++
Assert est une fonction qui permet de vérifier une condition dans le code. Par exemple si le programmeur écrit assert(ptr != NULL) au début d'une fonction qui reçoit un pointeur ptr pour spécifier qu'il s'attend à ce que le pointeur soit toujours valide (= non ul) et qu'un jour la fonction est appelée avec une valeur nulle, on aura à l’exécution un message "assertion failed" indiquant le problème. ca évite de laisser continuer le code travailler avec des valeurs incorrectes.
Maintenant le bug peut provenir de ton code PB mais c'est plutôt rare (normalement les exceptions sont attrapées pour ne pas planter bêtement), ici on dirait plutôt que tu as mis le doigt sur un bug du moteur PB.
Hors ligne
Dans le timer, il y a un appel à une procedure stockée:
SQLCA.P_HSM_MAINT_LOGIN_CHECK(ldb_ret_code, ls_maint_status, ls_arg1, ls_arg2)
Voici la déclaration
SUBROUTINE P_HSM_MAINT_LOGIN_CHECK(ref double P_RET_CODE,ref string P_MSG,ref string P_ARG1,ref string P_ARG2) RPCFUNC ALIAS FOR "~"SPDR~".PK_FWK_SECURITY.~"P_HSM_MAINT_LOGIN_CHECK~""
Il n'y a que des parametres OUT, et pas de types particuliers.
L'appel se fait directement dans le code PB.
Mais je ne pense pas que le problème soit lié à la procédure stockée.
Par contre, plus loin dans le timer, il y a cette partie de code:
pstr_retrieval_argument_v5 lstr_arg ... // Check the maintenance time ldb_rc = This.wf_check_maint_time(ls_maint_status) If ldb_rc = -1 Or ldb_rc = 1 Then // Set the structure with the parameters lstr_arg.a_parm[1] = li_min lstr_arg.a_parm[2] = ls_maint_status lstr_arg.a_parm[3] = ldb_rc // Ask the user to close application: OpenWithParm(w_kill_session, lstr_arg, This) End If //If ldb_rc = -1 Or ldb_rc = 1 Then // MFPF-5086 Start - Add a test If Message.PowerObjectParm = lstr_arg Then lstr_arg = Message.PowerObjectParm IF IsValid(lstr_arg) And Not IsNull(lstr_arg) THEN IF lstr_arg.a_parm[1] = 1 THEN // The user is working, restart the timer: This.TriggerEvent("ue_ini_timer") ELSE // The user is not present, close the application: This.TriggerEvent(Close!) END IF END IF Else // Do nothing End If // MFPF-5086 Stop
La structure lstr_arg est une structure avec 1 élément qui est un tableau a_parm[] de type 'any' .
En cliquant sur le bouton Ignore du 1er message d'erreur, on peut encore avoir une petite info supplémentaire:
" Mismatched ANY data types in expression: any, long at line 120 in timer event of object w_mdi_mf. "
La ligne 120 correspond à la ligne ci-dessous:
IF lstr_arg.a_parm[1] = 1 THEN
Se pourrait-il que l'élément a_parm[1] soit NULL ? Ou bien pas de type long et qu'il ne puisse pas le comparer à '1', et que cela fairait planter l'application ?
Cette histoire the 'Assertion Failure' m'inquiète beaucoup.
Dernière modification par Thorben (26-09-2012 15:22:05)
Hors ligne
Ton li_min, c'est bien un integer?
Si tu modifies ta ligne 120 en ceci, il te dit quoi?
String ls_numeric ls_numeric = String( lstr_arg.a_parm[1] ) IF NOT IsNumber( ls_numeric ) THEN messagebox( "wrong datatype", ls_numeric ) ELSE IF Long( ls_numeric ) = 1 THEN //... END IF
NB:
Hors ligne