Code retour SQL

Résolu
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 - 13 mars 2013 à 17:00
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 - 28 août 2013 à 18:16
Bonjour,

Je me demandais comment récupérer le retour d'une exécution SQL.
Le problème est que sur un TQuery, ou un TIBSQL (paradox ou firebird), les procédure ExecQuery ou ExecSQL sont ... des procédures , et donc ne retournent pas de valeurs... Si la requête plante, je peux récupérer le code d'erreur par une gestion des exceptions (try / except), mais en cas de succès ??? (ce qui arrive heureusement le plus souvent... )

- Dans le cas d'un delete ou d'un update, j'aimerais récupérer le code retour généré (0 si aucun, x pour x enregistrements supprimés/modifiés)
- Dans le cas d'un insert, avec un champ autoincrémenté, firebird autorise le "returning", mais comment puis-je le récupérer dans delphi ?

Merci pour vos réponses.

Simon

15 réponses

sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
20 mars 2013 à 10:00
hé hé hé !
En y regardant de plus près, le composant TSQLQuery (composants dbExpress) propose bien un execSQL qui retourne un integer, lequel n'est autre que le nombre de lignes affectées par la commande exécutée !!! Pile poil !
Je pense que je vais les adopter, surtout qu'il m'ont été chaudement recommandés pour Firebird par Thierry LABORDE. Les composants IB étant propre à interbase, on risque à terme d'avoir des problème de compatibilité avec Firebird. (En plus, ce n'est pas pour faire de la pub pour XE2, mais l'explorateur de données dbExpress est quand même super pratique...)

Simon
3
solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 10
13 mars 2013 à 20:03
Bonjour,
A priori on ne peut pas.
Ni en delphi, ni qvec interbase.
D'autres DB comme DB2 d'IBM disposent d'une variable SQLCOD qui retourne l'erreur (0 si ok), mais je n'ai pas trouvé non plus.
Si tu trouves ...
solilog
0
jderf Messages postés 189 Date d'inscription mercredi 29 décembre 2004 Statut Membre Dernière intervention 2 octobre 2014 1
13 mars 2013 à 22:06
Bonsoir,

Je n'ai pas l'habitude du TQuery, mais c'est un descendant du TDataSet donc tu peux faire pour le Insert qui retourne une clé :

MonTquery.SQl.Add('Insert ....returning Id_table')
MonTquery.Open // et pas ExecSQL car il retourne une donnée
MonId := MonTquery.FieldValues['Id_table']


Pour le delete et l'update, tu utilises MonTquery.RowsAffected

Dans des cas plus compliqués, je fais appel à une procedure stockée, pour faire des vérifications avant un delete et me retourner un code erreur "maison"

A+
Jean
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
15 mars 2013 à 12:08
Merci pour l'idée jderf, mais... ça ne marche pas.
J'ai utilisé un SQLQuery (composants dbExpress), il me retourne bien le champ, mais n'enregistre pas la ligne...


Simon
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jderf Messages postés 189 Date d'inscription mercredi 29 décembre 2004 Statut Membre Dernière intervention 2 octobre 2014 1
15 mars 2013 à 21:30
Bonsoir Simon,

Tu parles du cas de l'insert ?
Je l'utilise avec Firebird et cela fonctionne parfaitement. C'est peut être lié au compo, mais j'en doute. Dans mon cas c'est ZQuery.

Bizarre y'a pas un hic au niveau de la clé primaire qui bloque l'insert ?

A+
Jean
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
15 mars 2013 à 23:29
Bé, je suis sur firebird aussi. Je n'utilise pas le zquery par contre. La clé primaire est le générateur. J'essaierai avec ton composant pour voir si ça vient de là...

Simon
0
beckerich Messages postés 302 Date d'inscription jeudi 29 septembre 2005 Statut Membre Dernière intervention 17 septembre 2013 2
16 mars 2013 à 11:55
BONJOUR,

tu fais ton insert, et puis direct derrière un select max(clé primaire), le tout dans une transaction.
ça peut marcher comme cela. Travailles-tu en multi-postes ? si c'est en mono-poste, pas de problème.

Luc.
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
18 mars 2013 à 14:33
bonjour,

Dans le cas d'un delete ou d'un update, j'aimerais récupérer le code retour généré (0 si aucun, x pour x enregistrements supprimés/modifiés)

tu peux exécuter un SELECT COUNT(*) from Matable Where mêmes critères que pour ta requête en cours(delete ou update)

si ta requête s'exécute avec succès, tu as directement le nombre d'enregistrements concernés que tu peux même de ce fait annoncer avant le click :
"attention, vous allez modifier ou supprimer X enregistrements.."

cantador
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
18 mars 2013 à 14:47
Merci Cantador,
Ce qui est dommage c'est de ne pas pouvoir le faire en une seule requête. C'eut été appréciable que la procédure ExecSQL soit en fait une fonction avec en resultat le code retour SQL. Je m'étonne même que ce n'ait pas été demandé sur Delphi depuis le temps. Je vais regarder la propriété RowsAffected, peut-être qu'elle fera mon bonheur...


Simon
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
18 mars 2013 à 22:38
ce n'est pas un problème delphi mais
une fonctionnalité absente de certains sgbd..

cantador
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
19 mars 2013 à 09:25
Bé, absent du SGBD, je ne suis pas sûr dans la mesure où quand j'attrape une erreur sur un Except, j'ai bien un code retour à la manière des abend db2. D'ailleurs, en parlant de db2, c'est bien un SGBD supporté par delphi... Y a t'il des developpeurs Delphi/DB2 dans la salle ?

Simon
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
19 mars 2013 à 11:00
code retour à la manière des abend db2

oui, c'est normal, delphi peut renvoyer le code erreur dès l'instant où celui-ci est prévu dans le sgbd.

mais si la fonctionnalité n'existe pas alors delphi ne pourra à fortiori rien te retourner sauf bien sûr une erreur d'exécution impossible comme une division par zéro par exemple.

je n'utilise pas dbase.

cantador
0
solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 10
20 mars 2013 à 13:53
T'es vraiment use star cantador
solilog
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
25 mars 2013 à 23:16
@simonpelloquin:
oui pour tout
en te précisant qu'il existe aussi
des composants spécifiques Interbase.
@solilog:
oh oui très certainement, mais mon épouse trouve que
j'ai encore de bons restes..

alors..

cantador
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
28 août 2013 à 18:16
Bonjour !

Je reviens vers vous pour vous indiquer que le "returning" fonctionne avec Firebird/DBExpress.

Il faut utiliser la propriété "Active" ou la méthode "Open" au lieu de la méthode "ExecSQL", comme dans le code ci-dessous (avec une table TBL_TEST(NUMERO : smallint autoincrémenté par un trigger, et PRENOM varchar(50)) :

procedure TForm4.Button1Click(Sender: TObject);
var
   dbxTrans : TDBXTransaction;
   lsOut    : string;
begin
     dbxTrans := PREVISIONS.BeginTransaction;
     try
        with TSQLQuery.Create(nil) do begin
             SQLConnection := PREVISIONS;
             SQL.Add('Insert into TBL_TEST(PRENOM)');
             SQL.Add('Values (''Simon'')');
             SQL.Add('Returning NUMERO');
             Open;
             // Recupération de NUMERO
             lsOut := Fields[0].AsString;
             Free;
        end;
        ShowMessage(lsOut);
        PREVISIONS.CommitFreeAndNil(dbxTrans);
     Except
           ShowMessage('ERREUR');
            PREVISIONS.RollbackFreeAndNil(dbxTrans);
     end;
end;

0
Rejoignez-nous