Impostazioni di compatibilità – o guida con il freno di stazionamento inserito (Parte 1)

Tradotto automaticamente da Deepl

Nelle cucine del codice, di solito passo un po’ di tempo con le impostazioni del database, in particolare con le impostazioni di compatibilità. Spesso alcune impostazioni non seguono le best practice e durante le discussioni con lo sviluppatore dell’applicazione sento dire “oh, non le ho mai cambiate” o “non sono sicuro dell’impatto, quindi meglio non toccarle”.

Poiché potrebbero avere un impatto drastico sulle prestazioni o sul comportamento delle applicazioni, abbiamo iniziato una serie di post sul blog per discutere alcune di queste impostazioni “segrete“.

Parte 1 delle impostazioni di compatibilità – QUERY PER FORMULA

Queste impostazioni costringono 4D a comportarsi come nella versione 2004, riducendo le funzionalità e le prestazioni. È facile modificarle, ma i clienti temono effetti collaterali sconosciuti.

QUERY BY FORMULA era piuttosto lento nella v2004 (perché tutti i record venivano trasferiti al client), senza un grande valore aggiunto. Di conseguenza, la maggior parte degli sviluppatori la ignorava. Le regole sono state cambiate con la v11.

Il comando QBF (per non farla lunga in questo blog post) consente di utilizzare calcoli come la ricerca delle dimensioni delle immagini o della lunghezza del testo. I vantaggi di questa funzione sono abbastanza ovvi. Tuttavia, calcoli di questo tipo non possono utilizzare un indice, quindi sono più lenti di una query indicizzata.

Ma il comando QBF può fare molto di più! Può combinare gruppi di query con parentesi: ((campo1=1) e (campo2=”A”)) OPPURE ((campo1=50) e (campo2=”B”)).

Non utilizzare il comando QBF significa eseguire due query e utilizzare i gruppi, con conseguente aumento del traffico di rete, della dipendenza dalle prestazioni della rete e del carico del Server 4D. L’ottimizzatore di query di 4D Server rileva automaticamente il modo migliore (più veloce) per gestire tali condizioni sui campi della stessa tabella o anche di tabelle correlate.

E soprattutto, è in grado di creare da solo le relazioni (alias join), anche se non è stato tracciato alcun collegamento in modalità struttura. Sì, è possibile creare relazioni in modo dinamico per eseguire le query (se l’opzione “QUERY BY FORMULA Uses SQL Joins” è attivata).

L’opzione “QUERY BY FORMULA Uses SQL Joins” potrebbe confondere perché non è affatto correlata all’SQL; si dovrebbe pensare piuttosto a “QBF supporta le relazioni dinamiche”.

Utilizziamo una struttura semplice come esempio:

blank

Sia QUERY e QUERY BY FORMULA possono essere utilizzati per effettuare ricerche utilizzando una relazione, ad esempio:

QUERY BY FORMULA([Table_2];[Table_1]Field_2="1")

Ma solo QBF permette di definire esplicitamente la relazione (consentendo l’uso di qualsiasi relazione possibile), invece di richiedere che esista già una relazione definita. Immaginiamo ora che esista una seconda connessione logica tra queste due tabelle, ma che non esista già come relazione 4D… Campo3 con Campo2. QBY consente di specificare la relazione al volo:

QUERY BY FORMULA([Table_2]; ([Table_1]ID=$var)& \
([Table_1]Field_2=[Table_2]Field_3))

Nota: quando si utilizzano le giunzioni dinamiche, si devono confrontare due campi di tabelle diverse. Se fa parte di una query, questo viene gestito automaticamente come un join, per definire una relazione.

Se si vuole cercare un valore in un’altra tabella, bisogna prima assegnarlo a una variabile locale. In questo modo si definisce chiaramente che la si vuole usare come costante.

L’abilitazione dell’opzione “QUERY BY FORMULA Uses SQL Joins” è obbligatoria per consentire al “nuovo” editor di query(cioè l’editor di query introdotto con la v14) di utilizzare le relazioni. Il motivo è semplice: utilizza il comando QUERY BY FORMULA internamente.

Riepilogo:

  • QUERY BY FORMULA consente di utilizzare le parentesi per esprimere condizioni di query complesse, mentre QUERY consente solo condizioni multiple OR o AND, ma non una combinazione di entrambe.
  • QUERY BY FORMULA supporta i join e le query dinamiche.
  • QUERY BY FORMULA consente l’uso di formule, come la dimensione dell’immagine.
  • QUERY BY FORMULA viene eseguito sul server (in modo simile a un normale QUERY), fornendo la stessa velocità, se non addirittura una velocità migliore, perché genera meno traffico di rete rispetto a una combinazione di operazioni di QUERY e operazioni di set.

Nota: tutto quanto detto sopra vale per il linguaggio 4D classico. Il codice basato su ORDAviene sempre eseguito sul server.

Lavoro di migrazione necessario per abilitare la compatibilità

Le impostazioni di cui sopra sono visibili nella finestra di dialogo Compatibilità solo per le strutture create con 4D v2004 o precedenti. Se non vedete queste impostazioni, la vostra struttura è più recente e si comporta sempre in modalità v11, quindi siete a posto!

Usare l’opzione Trova in modalità di progettazione per cercare QUERY BY FORMULA. Poiché la struttura è in modalità “lenta” v2004, l’elenco dovrebbe essere breve. Fate doppio clic su ogni risultato e verificate il codice.

Finché la formula utilizza delle costanti, come ad esempio:

QUERY BY FORMULA([Table_2];[Table_1]Field_2="1")

Oppure

QUERY BY FORMULA([Table_2];[Table_1]Field_2=$var) // similar for var or <>var

Tutto va bene, non c’è nulla da fare. 4D Remote interpreta la variabile e invia il suo contenuto al server (come una costante). Il valore del client viene sempre utilizzato, anche se la query viene eseguita dal server.

Se la formula è un metodo, come ad esempio:

QUERY BY FORMULA([Table_2];RunQuery)

È necessario aprire e controllare il contenuto del metodo. Se al metodo vengono passati dei parametri, è probabile che il metodo sia generico (ma bisogna comunque controllare). Se non vengono passati parametri, è probabile che il metodo fallisca.

Si immagini che RunQuery contenga:

$0:= ([Table_2]=myvar)

Il contenuto di myvar sarà diverso su 4D Remote e 4D Server, quindi l’esecuzione di questo metodo su 4D Server fallirà. Verranno restituiti risultati diversi.

Ci sono due modi per risolvere questo problema. Per le query semplici come quelle sopra descritte, si può semplicemente riscrivere il metodo come RunQuery(myvar) e all’interno del metodo utilizzare $1. Il problema è risolto.

Ma si potrebbe trovare un metodo davvero complesso. Migliaia di righe di codice, nessuna documentazione, scritto 20 anni fa. E usato solo una volta all’anno. Si tratta di un sacco di lavoro e di rischio di errori, per un impatto minimo. Per ovviare al problema, si può scegliere di eseguire questo codice solo in modalità v2004, mantenendo tutto il resto in modalità moderna:

SET DATABASE PARAMETER(Query by formula on server;1)
QUERY BY FORMULA ([Table_2];RunQuery )
SET DATABASE PARAMETER (Query by formula on server;0)

SET DATABASE PARAMETER permette di cambiare la modalità al volo, evitando di passare ore e ore sul codice usato raramente.

Infine, è necessario verificare se i campi sono utilizzati in modo da danneggiare la funzione di unione. Con la v2004 una formula come [Table_1]Field_2=[Table_2]Field_3 viene interpretata come una ricerca di contenuti statici/fissi, utilizzando il contenuto del campo_3. Dopo aver abilitato l’opzione “QUERY BY FORMULA Uses SQL Joins”, questa viene interpretata come un join.

È quindi necessario controllare ogni QBF per verificare se utilizza un nome di campo sul lato destro di un operatore “=”. In caso affermativo, assegnarlo a una variabile locale e utilizzare la variabile locale nella query.

Dopo aver controllato tutte le occorrenze di QUERY BY FORMULAsi è pronti ad abilitare entrambe le opzioni.

Ricerca veloce…

Thomas Maul
• VP of Strategy, 4D Product Line • When 4D's German subsidiary was created in 1988, Thomas joined the company as a Technical Director, helping to build the 4D developer community in both Germany and Austria. After many years supporting customers with technical problems and being increasingly involved in sales and management issues, he was promoted to Managing Director for 4D Germany in 1999. As a member of the executive board since 2005, he became part of worldwide strategy of the company, leading to his current position as Vice President of Strategy, 4D Product Line, responsible for defining and executing the overall strategy for the 4D product line in relation to the Program, R&D, Sales and Marketing teams.