Appel de Procédure stockée avec PostgreSQL

Bonjour,
On voudrait savoir si on a un moyen pour appeler un Procédure stockée en base de donnée depuis simplicité?

[Platform]
Status=OK
Version=5.2.38
BuiltOn=2023-04-20 10:56
Git=5.2/66dd3f848850f0ba670a5f92674282285b3d3341
Encoding=UTF-8
EndpointIP=172.20.116.194
EndpointURL=http://mla-api-88d876694-ztptx:8080
TimeZone=Europe/Paris
SystemDate=2023-05-31 15:24:08
Lbouzidi

Cf. cette méthode: callProcedure

1 Like

Merci pour ton retour David.
Pouvez vous nous donnez un exemple svp pour qu’on puisse appeler cette méthode.
Le besoin est d’appeler la procédure depuis simplicité “procedure_with_insert(varchar)” qui agit sur une table qui n’est pas à un object DB (procedure_insert ) .
Je ne sais pas si c’est possible?
Je vous remercie d’avance

Je n’ai jamais utilisé cette methode mais l’appel dans ce cas doit être du type:

getGrant().callProcedure(
  null, // null = datasource par défaut, sinon le nom d'un datasource 
  "ma_proc",
  Arrays.asList(getField("mon_attribut"))
);

Il est possible de créer un object field temporaire si besoin:

ObjectField f = new ObjectField(ObjectField.TYPE_STRING);
f.setValue("mon argument");
getGrant().callProcedure(null, "ma_proc", Arrays.asList(f));

PS: idéalement il faudrait quelques variantes de cette méthode pour que ça soit plus simple à utiliser

  • sans argument datasource pour taper par defaut dans le datasource par défaut
  • avec une liste non pas d’object fields mais de simples valeurs

On les ajoutera peut être dans une prochaine révision

Bonjour @david,

On a fait le test avec l’exemple que tu nous as fourni, malheureusement cela ne fonctionne pas.

Voici le logs qu’on a eu :

Merci d’avance de ton aide.

Laila

@Francois je vais devoir te donner la main sur ce post.

Bonjour,

C’est bien ce que fait Simplicité en passant les hosts values :

Connection conn = getConnection(datasource);
try (CallableStatement stmt = conn.prepareCall("{ call as_abc_dq.procedure_with_insert(?) }")) {
	for (int i=0; params!=null && i<params.size(); i++)
		setHost(stmt, i+1, params.get(i));
	if (stmt.execute()) ...

Bizarre, c’est peut être à cause de l’espace entre le “{” et le “call”, ou CALL en minuscule.
Rien de bien clair dans les docs PGSQL, l’exemple est {call ....}
https://jdbc.postgresql.org/documentation/callproc/

Vous pouvez lancer vos requêtes directement via

getGrant().query("select ...", hosts);
getGrant().update("insert ...", hosts);
getGrant().update("update ...", hosts);
getGrant().update("delete ...", hosts);

Quel est le besoin de passer par une procédure stockée ?
Cette méthode callProcedure existe depuis 15 ans mais n’ai jamais utilisée (historiquement elle servait pour Oracle qui limitait pas mal de choses via JDBC).

Bonjour @Francois,

Nous avons un besoin coté Renault d’interfacer notre base de données avec un autre logiciel (IDQ).

IDQ va créer de nouveaux schémas sur la BDD. La responsabilité de ces tables sera gérées par IDQ.

IDQ n’ayant pas la main sur Simplicité, il souhaite que nous puissions déclencher certain JOBs (SQL), à la suite de certaines actions coté Simplicité. Ces JOBs seront maintenus par IDQ (ils sont donc susceptibles de changer).

C’est pour cela que l’utilisation de procédure a été retenue.

Pensez vous pouvoir corriger le problème ? et pouvoir le back porter en version 5.2 ?

Cette fonctionnalité est attendue par l’équipe IDQ.

Merci d’avance.

Laila

Oui on va corriger sur PGSQL
En terme d’architecture c’est très old school de coupler vos métiers ce cette manière / QoS, perfs…
Si un traitement UI ou Cron prend du temps vous ne saurez pas dire ce qui en est la cause.

1 Like

Le correctif est poussé en 5.3. Il sera backporté en 5.2 prochainement.

Un contournement possible au callProcedure est de créer une fonction qui appelle la procédure (ou qui fait la même chose).

Ensuite elle peut s’appeler via un simple select myFunc(12345, 'param'...)
en passant par getGrant().simpleQuery("select ...").

1 Like

Bonjour @Francois,

Je te remercie pour ton retour.
Avez vous une date pour le backportage en 5.2 ?
En attendant nous allons testé la solution que vous avez proposé.

Merci,

Laila

Bonjour @Francois,

Nous avons testé d’appeler une procédure à travers une fonction, l’appel se fait sans erreurs mais la procédure n’est pas exécutée (insert into).

On a aussi testé d’appeler la fonction avec un simple select count(*) et on a constaté que cela marche par contre l’insertion et l’update ne fonctionne pas.

Pour information, on a bien vérifié les droits sur la table, fonction et procédure.

Merci,
Laila

Cela ne relève plus trop de notre support car concerne PGSQL et les droits du user sur votre schéma externe/intégré. Il faudrait voir s’il y a des logs côté PG qui indiquent le problème, car vous l’aurez aussi surement en procédure.

A priori c’est faisable, testez déjà “à la main” que la fonction fonctionne via prompt sql, puis par DB Access sans passer par Java :

Bonjour @Francois,

On a déjà fait le test directement en base de données, l’appel de la fonction marche et on a bien les insertions et les updates. (aucun erreur remontée même en activant les log sql)

On a aussi vérifié les droits coté base de données ( Le user simplicité admin a tous les droits ainsi que le fonction et la procédure appelée )

En utilisant le requêteur simplicité a cela la valeur de retour mais aucune insertion n’est effectuée

Merci,
Laila

NB : Au début on avait bien un problème de droits et on le voyait dans les logs simplicité, et on a corrigé cela en donnant tous les droits au user simplicité admin.

Ok si la fonction est OK en direct, la différence c’est que DBAccess passe par le driver JDBC installé sur Tomcat pour exécuter la commande “select” via un “prepareStatement” classique.
La fonction fait elle un commit explicite ?

Mes compétences s’arrêtent là sur le sujet et Simplicité n’a pas été testé pour ce genre d’intégration bas niveau.

Vous pouvez ouvrir une connexion Java avec la base sans passer par les couches simplicité, via InitialContext lookup de la ressource nommée “jdbc/simplicite” ou autre resource/base externe

Une fois votre connexion ouverte vous êtes libres de vos appels de procédure via prepareCall ou de fonction via prepareStatement.

Mais encore une fois, c’est faire dans Simplicité des choses qui n’ont rien à y faire / non debuggable, non monitorable…

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.