It is currently 9 June 2025, 5:14 Advanced search

forEachCount senza eseguire la query?

Domande e risposte su come utilizzare Instant Developer Foundation al meglio

forEachCount senza eseguire la query?

Postby f.faleschini » 3 May 2024, 9:36

Ciao.

Spesso per migliorare le performance delle applicazioni mi ritrovo a usare una foreach select (readonly).

Di recente è stato aggiunto il metodo forEachCount() per conoscere dentro il foreach il totale delle righe.

Sempre per motivi di performance a volte non vorrei eseguire la query se il conteggio è zero.

Esempio: in una videata clienti non voglio mostrare il pulsante "mostra fatture" se il conteggio delle fatture è zero. Se però il cliente ha 100000 fatture devo tirarle su tutte solo per contare. L'esempio è infelice, lo so, ma il concetto è: uscire dal foreach "prima di lanciare la query"...

Ora in questo esempio io carico le fatture con una foreach select e dentro al loop se forEachCount è 0 faccio break.

Il workaround è fare una select into variables count query duplicando la query foreach, però mi tocca scrivere due query quasi uguali (una per il select into variables e una per il foreach) che è una duplicazione di codice "fastidiosa".

C'è un modo per farlo o sarebbe una proposta di modifica?

Quello che ho in mente è: quando si fa una foreach select:
1. prima inde fa in automatico una count query
2. lo sviluppatore ha a disposizione un modo per scrivere del codice nel caso di count 0 e eventualmente fare break
2. quindi inde fa la query vera e si prosegue al modo solito

Per intenderci, qualcosa del genere:
Code: Select all
for each row (readonly)
{
  select
     IDFattura= Fatture.IDFattura
     importo= Fatture.Importo
     altriCampi= AltreTabelle.AltriCampi
  from
     Fatture// master table
     AltriCampi// joined with Fatture...
  where
    CONDITION

specialCodeForForEachCountZero -- nota: questa è un'area speciale dentro il foreach che inde mi metterebbe a disposizione per gestire il caso forEachCount()==0
{
  this.totaleFattureCount = 0
  break
}

normalCodeForForEachCountGreaterThanZero  -- nota: questa è un'area speciale dentro il foreach che corrisponde a quello che si fa attualmente in un foreach dopo la query
{
  faiQuelloCheDeviFare
}

}


avendo a disposizione "l'area di codice" specialCodeForForEachCountZero avrei modo di evitare di lanciare la query principale in modo facile.

Il workaround attualmente possibile è

Code: Select all
// prima conto a mano
int vCount = 0
select into variables (found variable)
  set vCount = count([expression])
  from
     Fatture// master table
     AltriCampi// joined with Fatture...
  where
    CONDITION

// in caso di conteggio zero faccio quello che devo fare
if vCount  ==0
{
  this.totaleFattureCount = 0
}
// altriementi lancio la query (che potrebbe anche essere molto impegnativa)
else
{
for each row (readonly)
{
  select
     IDFattura= Fatture.IDFattura
     importo= Fatture.Importo
     altriCampi= AltreTabelle.AltriCampi
  from
     Fatture// master table
     AltriCampi// joined with Fatture...
  where
    CONDITION

  faiQuelloCheDeviFare
}


C'è un modo per fare già (senza il workaround) il conteggio?

Grazie!
f.faleschini
 
Posts: 1075
Joined: 12 April 2017, 9:09

Re: forEachCount senza eseguire la query?

Postby r.bianco » 3 May 2024, 10:22

Non ho capito. Se la qry del for each non ha record, il ciclo non viene eseguito, giusto? Oppure ho perso un pezzo del ragionamento?
only work and no play makes jack a dull boy
r.bianco
 
Posts: 4979
Joined: 8 November 2010, 16:46

Re: forEachCount senza eseguire la query?

Postby f.faleschini » 3 May 2024, 14:49

r.bianco wrote:Non ho capito. Se la qry del for each non ha record, il ciclo non viene eseguito, giusto? Oppure ho perso un pezzo del ragionamento?

Grazie per la risposta.

Se la query del foreach non ha record non ha record non ci sono problemi, il caso è se ci sono record e io voglio evitare di lanciare la query.

Quello che voglio ottenere lo si fa già con una "select into variables count from STESSE_TABELLE_DELLA_QUERY_DEL_FOREACH" e poi se count != 0 fai il foreach

però così devo scrivere due query quasi uguali, che è una duplicazione di codice. Se il foreach fa il join di 6 tabelle e ci sono 8 righe di where condition questo è un problema.

Mi chiedevo se inde potesse evitarmelo fornendomi un ForEachPotenziato che mi fa gestire il caso di forEach senza risultati.

in queste righe ho riscritto il post originale in altre parole. ciao!
f.faleschini
 
Posts: 1075
Joined: 12 April 2017, 9:09

Re: forEachCount senza eseguire la query?

Postby dr_whiteriver » 3 May 2024, 15:06

Ciao io userei solo un for each row, una cosa tipo:

int qRighe= 0;

for each row (readonly)
{
select
IDFattura= Fatture.IDFattura
importo= Fatture.Importo
altriCampi= AltreTabelle.AltriCampi
from
Fatture// master table
AltriCampi// joined with Fatture...
where
CONDITION

qRighe ++;

faiQuelloCheDeviFare
}

if (qRighe == 0){
....
}
else {
....
}

Non so se ti può essere utile come idea...
Alessandro
User avatar
dr_whiteriver
 
Posts: 570
Joined: 3 September 2012, 13:44

Re: forEachCount senza eseguire la query?

Postby f.faleschini » 3 May 2024, 16:23

Grazie, però facend come dici tu lui fa comunque la query completa e se la query sta 20 secondi per completarsi è uno spreco di risorse, quello che vorrei io è un count automatico fatto dal foreach. Al limite un foreach con un'opzione "precount" da settare da VCE , un po' come in select into variables c'è il parametro "foudn variable", in un "posto" simile nel foreach metterei "execute precount"...
f.faleschini
 
Posts: 1075
Joined: 12 April 2017, 9:09


Return to Tips & Tricks - Foundation

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Majestic-12 [Bot] and 47 guests

cron