Depuis la version Harmony 410 il est possible de créer des tables temporaires SQL
Les caractéristiques des tables temporaire
Syntaxe
[public | protected | extern] TmpRecordSql[KeepDataNames] dico mnémo Instance [KeepOnExit][NoCreate]
La table est créée en dupliquant la table d'origine de la base (colonnes et index).
Il faut donc que cette table soit existante dans la base, on ne crée pas à partir du dico dhsd
La table est supprimée automatiquement
lorsque le xrtdiva qui a créé la table se termine
en fin de fonction
en fin de programme (sauf si l'option KeepOnExit est positionnée)
Option KeepOnExit
Permet de ne pas supprimer la table temporaire à la fin du programme Diva
Cela permet de faire des programGoto en passant le nom de la table temporaire
On utiliser alors GetTemporaryTableName/SetTemporaryTableName
Get permet de récupérer le nom de la table temporaire
Set permet de le positionner.
On ping le nom de la table, on le récupère par pingReceive et on le positionne par SetTemporaryTableName
Attention : il y'a un risque avec ProgramCall NO_WAIT : la table est supprimée si le père s'arrête. Il ne faut donc pas utiliser les tables temporaires dans ce cas
La bonne pratique est que celui qui créer la table temporaire fasse appel a un traitement en call wait, puis qu’au retour la fin du programme détruise la table temporaire
Option NoCreate
A utiliser lorsqu’un traitement ne fait que lire une table temporaire créée ailleurs
Exemple Diva
Voici deux exemples commentés
Table temporaire dans un traitement
;* Procedure Record_temporaire_View ;* Declaration_VueTiers TmpRecordSql gtrstiers.dhoq VueTiers V1 1 ReaderIdVue L 1 compteur_R L = 0 1 compteur_T L = 0 1 ReaderId L Beginp ReaderIdVue = ReaderOpen_VueTiers (VueTiers,ReaderIdVue) VueTiers.OrderBy.Par_Nom() ReaderSelect_VueTiers (VueTiers ,ReaderIdVue) ReaderBegin_VueTiers (VueTiers ,ReaderIdVue) do while ReaderNext_VueTiers(VueTiers,ReaderIdVue) = 0 V1.TIERS_VIEW = VueTiers.TIERS_VIEW V1.Insert() compteur_R++ wend ReaderClose_VueTiers(VueTiers,ReaderId) ReaderId = ReaderOpen_VueTiers(V1,ReaderId) V1.OrderBy.Par_Nom() ReaderSelect_VueTiers (V1 ,ReaderIdVue) ReaderBegin_VueTiers (V1 ,ReaderIdVue) do while ReaderNext_VueTiers(V1,ReaderIdVue) = 0 compteur_T++ wend ReaderClose_VueTiers(V1,ReaderId) V1.getinfo(RSQL_ALIAS_TABLE_ID,nom) V1.getinfo(RSQL_TABLE_NAME,nom) nom = V1.GettemporaryTableName() Endp
On déclare ici un TmpRecordSql sur un recordSql avec un instance V1
Instance locale à la procedure
Lecture en boucle de la vue tiers
Recopie des données à l’identique dans cet exemple
Insertion dans V1 qui devient une table temporaire
Relecture de la table temporaire pour comparer les compteurs en debug
Lecture d’informations complémentaire en debug pour constater que la table porte un nom temporaire
Table temporaire dans 2 traitements distincts
Le but est d’avoir un traitement qui créé les données temporaires, et un second qui les lit
TmpRecordSql gtrsart.dhoq Article A2 KeepOnExit ;* Procedure Record_temporaire_Article ;* 1 nom S Declaration_Article 1 ReaderId L Beginp ReaderId = ReaderOpen_Article(Article,ReaderId) Article.OrderBy.Par_Reference() ReaderSelect_Article(Article,ReaderId) ReaderBegin_Article(Article,ReaderId) Do while ReaderNext_Article(Article,ReaderId) = 0 A2.ART = Article.ART Insert_Article(A2) wend ReaderClose_Article(Article,ReaderId) ;récupération du nom de la table temporaire et envoi par ping nom = A2.GettemporaryTableName() Ping('nom_tmp',Nom) Programcall('TraitementRSQLTmp.dhop') Endp
On déclare ici un TmpRecordSql sur un recordSql en global avec un instance A2 avec KeepOnExit
(pas en local!)
Lectrure en boucle des article
Recopie des données à l’identique dans cet exemple
Insertion dans VA2 qui devient une table temporaire
Récupération du nom et appel au second traitement
TmpRecordSql gtrsart.dhoq Article A2 NoCreate KeepOnExit 1 compteur_T L = 0 1 ReaderId L Main mz.Dos = '998' load_gtfdos(mz.Dos) PingReceiveAnddelete('nom_tmp',Nom) A2.SetTemporaryTableName(nom) ReaderId = ReaderOpen_Article(A2,ReaderId) A2.OrderBy.Par_Reference() ReaderSelect_Article(A2,ReaderId) ReaderBegin_Article(A2,ReaderId) Do while ReaderNext_Article(A2,ReaderId) = 0 compteur_T++ wend ReaderClose_Article(A2,ReaderId)
On déclare ici un TmpRecordSql sur un recordSql en global avec un instance A2 avec NoCreate et KeepOnExit, car le traitement ne fait qu'exploiter (pas de création) et doit laisser l’appelant gérer la destruction
Récupération du nom de la table temporaire
Affectation au recordSql temporaire du nom
Lecture de la table temporaire