|
PROFESSIONAL NEWSGROUPS WINDEV, WEBDEV and WINDEV Mobile |
| | | | | |
Home → WINDEV 2024 → Procédure stockée SQLServer, problème incompréhensible? |
Procédure stockée SQLServer, problème incompréhensible? |
Started by pkeNOSPAMPLZ, Mar., 28 2006 11:36 AM - 4 replies |
| |
| | | |
|
| |
Posted on March, 28 2006 - 11:36 AM |
Bonjour
Dans un projet je suis amené à utiliser des procédures stockées sur un serveur SQL (connexion àcelui ci via OLEDB). Je les utilise depuis Windev et Windev Mobile (donc je n'utilise pas les fonctions non gérées par la version Mobile du type "SQL..."). Malheureusement, je butais sur un problème récurent que je pense enfin avoir cerné et j'ai réalisé un projet plus simple afin de pouvoir vous exposer mon problème. En fait je me suis rendu compte que dès que ma procédure stockée contenait un UPDATE (voire un INSERT ou un DELETE dans certaines conditions) et que cette même procédure stockée renvoyait une valeur, cela générait une erreur dans WinDev. Si je ne fais qu'un update ou un select pour remplir la valeur de retour ça va mais si je fais les deux, ça ne passe plus!
Pour vous présenter cela de manière plus "pratique" voici un petit projet que j'ai réalisé : une table sur SQL Server composée de 3 champs (Nom, Prénom et Compteur), une fenêtre avec 2 text box (une appelée txtNom et l'autre txtPrénom), et 3 boutons (le premier lance une procédure stockée contenant uniquement un SELECT, le deuxième de même mais la procédure contient un UPDATE et le dernier bouton lance lui une procédure qui reprend à l'identique le SELECT et l'UPDATE pré-cités). Voici le code du premier bouton, il fonctionne sans problème, il lance la procédure stockée (avec comme paramètre entrant le nom de la personne et comme paramètre de sortie son prénom) et après je récupère la valeur qu'elle me renvoie et l'affiche dans la text-box txtPrenom:
---------------------------- //Lance la procédure qui contient un SELECT, récupère une valeur de sortie (le prénom en fonction du nom transmis en paramètre). Après, on affiche celui-ci dans une text-box
sql est une chaîne reqTest est une Source de Données sql = "DECLARE @Recup_Param char(10) " sql+= "EXEC PROCEDURE_SELECT '" + txtNom + "', @Recup_Param OUTPUT " sql+= "SELECT @Recup_Param AS Prenom" SI PAS HExécuteRequêteSQL(reqTest,MaConnexion,hRequêteSansCorrection,sql) ALORS Erreur(HErreurInfo()) SINON HLitPremier(reqTest) SI PAS HEnDehors() txtPrenom = reqTest.Prenom FIN FIN ----------------------------
Voici le code de la procédure stockée que ce bouton lance(PROCEDURE_SELECT):
---------------------------- CREATE PROCEDURE PROCEDURE_SELECT @PARAM_IN char(10), @PARAM_OUT char(10) OUTPUT AS SELECT @PARAM_OUT = PRENOM FROM BD_TEST WHERE NOM = @PARAM_IN GO ----------------------------
Maintenant, voici le code du deuxième bouton qui lui, lance la procédure stockée (avec le nom en paramètre entrant) qui incrémente de 1 la valeur du compteur, tout fonctionne à nouveau sans aucun problème:
---------------------------- //Lance la procédure qui contient un UPDATE, on ajoute 1 au compteur de la personne dont on passe le nom en paramètre.
sql est une chaîne reqTest est une Source de Données sql= "EXEC PROCEDURE_UPDATE '" + txtNom + "'" SI PAS HExécuteRequêteSQL(reqTest,MaConnexion,hRequêteSansCorrection,sql) ALORS Erreur(HErreurInfo()) SINON Info("Ok, compteur mis à jour") FIN ----------------------------
Voici le code de la procédure stockée que ce bouton lance (PROCEDURE_UPDATE):
---------------------------- CREATE PROCEDURE PROCEDURE_UPDATE @PARAM_IN char(10) AS UPDATE BD_TEST SET COMPTEUR=COMPTEUR+1 WHERE NOM = @PARAM_IN GO ----------------------------
Enfin, voici le code du troisième bouton qui lance une procédure stockée qui reprend le SELECT et l'UPDATE des procédures précédentes. Ici, la procédure s'exécute, le compteur se met à jour, mais quand l'application arrive au HLitPremier(reqTest), elle plante avec une erreur bizarre que je mettrais plus bas:
---------------------------- //Lance la procédure qui contient le SELECT et l'UPDATE, récupère une valeur de sortie (le prénom en fonction du nom transmis en paramètre). Après, on affiche celui-ci dans une text-box. La procédure met également à jour le compteur de cette même personne.
sql est une chaîne reqTest est une Source de Données sql = "DECLARE @Recup_Param char(10) " sql+= "EXEC PROCEDURE_SELUP '" + txtNom + "', @Recup_Param OUTPUT " sql+= "SELECT @Recup_Param AS Prenom" SI PAS HExécuteRequêteSQL(reqTest,MaConnexion,hRequêteSansCorrection,sql) ALORS Erreur(HErreurInfo()) SINON Info("Ok, compteur mis à jour") HLitPremier(reqTest) SI PAS HEnDehors() txtPrenom = reqTest.Prenom FIN FIN ----------------------------
Voici la procédure en question (PROCEDURE_SELUP):
---------------------------- CREATE PROCEDURE PROCEDURE_SELUP @PARAM_IN char(10), @PARAM_OUT char(10) OUTPUT AS SELECT @PARAM_OUT = PRENOM FROM BD_TEST WHERE NOM = @PARAM_IN UPDATE BD_TEST SET COMPTEUR=COMPTEUR+1 WHERE NOM = @PARAM_IN GO ----------------------------
Et maintenant l'erreur générée:
---------------------------- Erreur à la ligne 13 du traitement Clic sur cmdSelectUpdate. Vous avez appelé la fonction HLitPremier. Fichier <reqTest> inconnu dans l'analyse <C:\Mes Projets\SQLServer\TestSqlServer.wdd>, ou requête ou vue non initialisée.
Informations techniques
Projet : TestSqlServer
Dump de l'erreur du module <WD100HF.DLL> <10.00Cg>.
- Appel WL : Traitement de <frmFenêtre1.cmdSelectUpdate>, ligne <13>, thread <0> Fonction <HLitPremier>, n° de syntaxe <3>
- Niveau : erreur fatale (EL_FATAL)
- Code erreur : 70018
- Code erreur WD55 : 18
- Pas de code d'erreur système
- Pas de message d'erreur système
- Que s'est-il passé ? Fichier <reqTest> inconnu dans l'analyse <C:\Mes Projets\SQLServer\TestSqlServer.wdd>, ou requête ou vue non initialisée.
- Infos de debug : iehf01 Fonction (7,10)
- Infos attachées : EIT_PATHWDD : <C:\Mes Projets\SQLServer\TestSqlServer.wdd> EIT_LOGICALTABLENAME : <reqTest> EIT_DATEHEURE : 28/03/2006 09:24:26 EIT_PILEWL : Clic sur cmdSelectUpdate (frmFenêtre1.cmdSelectUpdate), ligne 13
- Identifiant dans le .err : 70116 ----------------------------
Donc ça me dit que le Fichier <reqTest> est inconnu dans l'analyse, or il n'a rien à faire dans l'analyse c'est juste une source de données que j'ai bel et bien définie et qui a fonctionné sans problème dans les 2 cas précédentes mais qui débloque quand on fait les deux en même temps (c'est obligatoire pour moi de les faire en même temps dans mon projet car ils seront dans une seule et même transaction). La valeur du compteur est bel et bien mise à jour, mais ce qui pose problème c'est la récupération du paramètre que me renvoie la procédure.
Je ne comprend absolument pas l'erreur que Windev me renvoie, je trouve qu'elle n'a aucun rapport avec ce que je fais. De plus, ma PROCEDURE_SELUP fonctionne très bien en dehors de Windev elle n'est pas à mettre en cause. Ce n'est pas non plus la manière dont je récupère le paramètre puisque j'y arrive de cette manière avec le premier bouton dont j'ai parlé plus haut. Idem pour l'incrémentation du compteur qui fonctionne. Je reprend ces 2 procédures en une seule et c'est là que ça coince...
J'ai essayé tout ce que j'ai pu imaginer mais sans succès.
Si quelqu'un à une solution (sans les fonctions SQLFetch, SQLLitCol,... inutilisables sous la version Mobile), je lui en serai fort reconnaissant!
Merci à vous.
PS: je peux fournir sans problème le petit projet de test que j'ai réalisé si nécessaire. |
| |
| |
| | | |
|
| | |
| |
Posted on March, 28 2006 - 12:33 PM |
Avez-vous essayé HLitPremier("reqTest") ?
Personellement j'utilise plutôt la technique suivante :
Req est une chaîne Ret est une chaîne Cmd est une chaîne
Req="REQ"+DonneIdentifiant() Cmd="declare @OD_ID char(20), @AN_CODE char(5), @EtatODR smallint, @EtatANO smallint, @Ret SmallInt EXEC ChgODREtatCourrier @OD_ID='"+pOD_ID+"', @AN_CODE='"+pAN_CODE+"', @EtatODR="+pEtatODR+", @EtatANO="+pEtatANO+", @Retour=@Ret Output Select @Ret"
SQLTransaction(sqlDébut) SI PAS SQLExec(Cmd,Req) ALORS SQLErreur(Req,Cmd) SQLTransaction(sqlAnnule) RENVOYER Faux SINON SI SQLFetch(Req)=0 ALORS Ret = SQLLitCol(Req,1) SQLFerme(Req) FIN SI Ret=1 SQLTransaction(sqlFin) RENVOYER Vrai SINON SQLTransaction(sqlAnnule) RENVOYER Faux FIN FIN |
| |
| |
| | | |
|
| | |
| |
Posted on March, 28 2006 - 5:13 PM |
En effet j'ai essayé de mettre ou non des guillemets autour de reqTest mais cela n'y change rien.
J'ai essayé votre mthode (bien qu'elle ne puisse fonctionner pour mon application Mobile), et malheureusement la valeur de retour que j'affiche me revient systématiquement vide (pourtant la procédure stockée incrémente bien la bonne ligne donc pour moi elle la sélectionne tout aussi bien également).
Voici votre code que j'ai adapté pour mon projet:
SI NumConnexion = 0 ALORS SQLInfoGene() Erreur("Erreur d'ouverture de la connexion : " + SQL.MesErreur) SINON Ret est une chaîne Cmd est une chaîne Cmd = "DECLARE @Envoi_Param char(10) ,@Recup_Param char(10) " Cmd+= "EXEC PROCEDURE_SELUP @Envoi_Param='" + txtNom + "', @Retour=@Recup_Param OUTPUT SELECT @Recup_Param" SQLTransaction(sqlDébut) SI PAS SQLExec(Cmd,"Req1") ALORS Erreur("Erreur à l'exécution lors du SQLExec") SQLTransaction(sqlAnnule) SINON SI SQLFetch("Req1")=0 ALORS Ret = SQLLitCol("Req1",1) SQLFerme("Req1") FIN Info(Ret) SQLTransaction(sqlFin) FIN FIN SQLDéconnecte()
Et ma procédure stockée :
CREATE PROCEDURE PROCEDURE_SELUP @Envoi_Param char(10), @Retour char(10) OUTPUT AS SELECT @Retour = PRENOM FROM BD_TEST WHERE NOM = @Envoi_Param UPDATE BD_TEST SET COMPTEUR=COMPTEUR+1 WHERE NOM = @Envoi_Param GO
Et donc l' Info(Ret) affiche une fenetre vide... Si j'ai oublié quelque chose merci de me le signaler (d'ailleurs si vous pouviez m'indiquer comment vous garnissez @Retour dans votre procédure pour voir si vous faites comme moi, merci d'avance).
Merci de votre aide et de l'intérêt que vous portez à mon problème. |
| |
| |
| | | |
|
| | |
| |
Posted on March, 28 2006 - 10:10 PM |
Bonsoir,
Il manque un commit dans votre procédure. Une procédure doit être la plus autonome possible. Autre petite remarque, je ferais l'update avant le select.
-- Emmanuel Lecoester
"PatriceK" <pkeNOSPAMPLZ@sigroup.be> a écrit dans le message de news:44292e44$1@news.pcsoft.fr...
En effet j'ai essayé de mettre ou non des guillemets autour de reqTest
mais cela n'y change rien.
J'ai essayé votre mthode (bien qu'elle ne puisse fonctionner pour mon
application Mobile), et malheureusement la valeur de retour que j'affiche me revient systématiquement vide (pourtant la procédure stockée incrémente bien la bonne ligne donc pour moi elle la sélectionne tout aussi bien également).
Voici votre code que j'ai adapté pour mon projet:
SI NumConnexion = 0 ALORS SQLInfoGene() Erreur("Erreur d'ouverture de la connexion : " + SQL.MesErreur) SINON Ret est une chaîne Cmd est une chaîne
Cmd = "DECLARE @Envoi_Param char(10) ,@Recup_Param char(10) " Cmd+= "EXEC PROCEDURE_SELUP @Envoi_Param='" + txtNom + "',
@Retour=@Recup_Param OUTPUT SELECT @Recup_Param"
SQLTransaction(sqlDébut) SI PAS SQLExec(Cmd,"Req1") ALORS Erreur("Erreur à l'exécution lors du SQLExec") SQLTransaction(sqlAnnule) SINON SI SQLFetch("Req1")=0 ALORS Ret = SQLLitCol("Req1",1) SQLFerme("Req1") FIN Info(Ret) SQLTransaction(sqlFin) FIN FIN SQLDéconnecte()
Et ma procédure stockée :
CREATE PROCEDURE PROCEDURE_SELUP @Envoi_Param char(10), @Retour char(10) OUTPUT AS SELECT @Retour = PRENOM FROM BD_TEST WHERE NOM = @Envoi_Param UPDATE BD_TEST SET COMPTEUR=COMPTEUR+1 WHERE NOM = @Envoi_Param GO
Et donc l' Info(Ret) affiche une fenetre vide... Si j'ai oublié quelque
chose merci de me le signaler (d'ailleurs si vous pouviez m'indiquer comment vous garnissez @Retour dans votre procédure pour voir si vous faites comme moi, merci d'avance).
Merci de votre aide et de l'intérêt que vous portez à mon problème.
|
| |
| |
| | | |
|
| | |
| |
Posted on March, 29 2006 - 10:50 AM |
Merci pour les conseils ça ne résoud pas le problème mais c'est toujours bon à savoir. |
| |
| |
| | | |
|
| | | | |
| | |
| | |
| |
|
|
|