Esegui le query in background, attendi il loro completamento e fai riferimento ad esse nello script JSL rimanenteProblema
Desideri eseguire una query in background in modo che l'interfaccia utente non si blocchi oppure desideri eseguire più query contemporaneamente e quindi combinare i risultati. A volte è difficile inserire tutte le funzionalità necessarie nello script "on run complete" delle query in background.
Soluzione
Ogni query salva i risultati in un nuovo spazio dei nomi a cui possono accedere tutti gli script (query e lo script originale).Lo script originale continua a verificare i risultati prima di procedere.
//Example script which runs queries in the background and references their results
//once finished.
Names default to here(1);
// Namespace to share data between background query and this script
ns = new namespace( "queries" );
// Flags which the background query will set to 1 when the background query is complete
ns:query1isdone = 0;
ns:query2isdone = 0;
// Open a window to display results
win = New window("Query Status", show menu(0), show toolbars(0),
text box("Status of queries:"),
tb = tablebox( string col box( "Query" , { "Query 1", "Query 2" } ),
string col box( "Status", { "Not Started", "Not Started" } ) ),
tbStatus = text box("Starting queries.")
);
wait(0); //make sure window shows up
// Define and start background queries
// First Query
sql_query1 = New SQL Query(
Connection( "ODBC:DSN=Test Source;DATABASE=Test Database;" ),
QueryName( "Query" ),
Select( vars ),
From( table ),
Where( condition )
);
sql_query1 << Run Background( OnRunComplete(
Names default to here(1);<BR /> ns = namespace( "queries" );
ns:dt1 = queryResult;
ns:query1isdone = 1;
) );
// Second Query
sql_query2 = New SQL Query(
Connection( "ODBC:DSN=Test Source;DATABASE=Test Database;" ),
QueryName( "Query" ),
Select( vars ),
From( table ),
Where( condition )
);
sql_query2 << Run Background( OnRunComplete(
Names default to here(1);<BR /> ns = namespace( "queries" );
ns:dt2 = queryResult;
ns:query2isdone = 1;
) );
// Every second check if the query is done (timeout after 10 seconds)
i=0;
allqueriesdone = 0;
starttime = tick seconds();
while( ( i < 10 ) & allqueriesdone == 0 ,
i++;
wait(1);
if( ns:query1isdone == 1,
tb << delete row( 1 );
tb << insert row( 1, {"Query 1", "Complete"} );,
tb << delete row( 1 );
tb << insert row( 1, {"Query 1", "Still Running"} );
);
if( ns:query2isdone == 1,
tb << delete row( 2 );
tb << insert row( 2, {"Query 2", "Complete"} );,
tb << delete row( 2 );
tb << insert row( 2, {"Query 2", "Still Running"} );
);
if( (ns:query1isdone == 1 ) & (ns:query2isdone == 1 ), allqueriesdone = 1 ); //indicate that everything finished
tbStatus << Set Text( "Queries are running, " || format(tick seconds() - starttime, "Fixed Dec", 12, 1) || " seconds elapsed." );
win << bring window to front;
);
// Show an error if any queries didn't finish
if( allqueriesdone == 0,
tbStatus << Set Text("Error, a query didn't finish and is still running!"),
tbStatus << Set Text("Queries finished after " || format(tick seconds() - starttime, "Fixed Dec", 12, 1) || " seconds.");
//win << Close Window; //could close window here
);
// Now reference the data tables
show( ns:dt1 );
show( ns:dt2 );Desideri eseguire query in background ma devi interagire con i risultati.Questo metodo consente il completamento di più query in background prima di interagire con i risultati.
UtilitàRi: Esegui query in background, attendi che vengano completate e fai riferimento ad esse nello script JSL rimanenteCiao @MarkDayton ,
Grazie per aver approfondito questo aspetto poiché hai sottolineato una carenza della sceneggiatura che ho appena corretto. Non avevo nomi predefiniti qui(1) negli script OnRunComplete, quindi non funzionava esattamente come avevo pianificato.Ecco una descrizione degli spazi dei nomi prima e dopo l'aggiornamento I Appena fatto:
Panoramica
Nota come è lo spazio dei nomi "query". creato nello script genitore e poi referenziato negli script OnRunComplete.La variabile ns stessa viene utilizzata solo per fare riferimento alle "query" dello spazio dei nomi.Ad esempio, in una nuova finestra di script potresti eseguire:
Names default to here(1);
ns = New Namespace("queries");
ns:a = 1
e una seconda finestra di script potrebbe ottenere il valore di a chiamando:
Names default to here(1);
Show(Namespace("queries"):a);
ma non puoi accedere facilmente a ns nell'altra finestra. Puoi, tuttavia, definire una nuova variabile nell'altra finestra, quindi accedere a in modo simile:
Names default to here(1);
nsreference = Namespace("queries");
Show(nsreference);
Oppure, per rendere il codice più facile da leggere, potresti usare lo stesso nome di variabile in entrambe le finestre.Le variabili stesse sono diverse poiché sono definite in spazi dei nomi diversi, ma fanno riferimento alla stessa cosa in modo da poterle utilizzare allo stesso modo.
Names default to here(1);
ns = Namespace("queries");
Show(ns:a);
Ecco come vengono utilizzate le variabili nello script di esempio sopra: una variabile chiamata "ns" viene creata in ciascuno spazio dei nomi qui che fa riferimento alle "query" dello spazio dei nomi denominato, semplificando la condivisione di valori tra tali script.
Prima del cambiamento - come funzionerebbe senza avviare ogni script OnRunComplete con i nomi predefiniti qui (1):
Visualizza altro...
Dopo il cambiamento - come funziona lo script adesso
Lo script utilizza quattro spazi dei nomi:
- Lo spazio dei nomi here per la finestra dello script principale
- Lo spazio dei nomi here per lo script OnRunComplete della prima query
- Lo spazio dei nomi here per lo script OnRunComplete della seconda query
- Lo spazio dei nomi denominato "queries", a cui fanno riferimento sia lo script principale che i due script OnRunComplete
La variabile ns nello script genitore è definita nello spazio dei nomi qui to riferimento lo spazio dei nomi delle query, che viene creato con New Namespace().Ciò significa che solo la finestra dello script ha accesso a ns, ma qualsiasi altra cosa in quell'istanza di JMP può fare riferimento a qualsiasi cosa venga salvata nello spazio dei nomi delle query a cui fa riferimento ns.
Gli script OnRunComplete vengono aperti in un nuovo ambiente e non hanno accesso allo spazio dei nomi here dello script padre.Pertanto una nuova variabile chiamata anche ns è definita nello spazio dei nomi qui di quello script ed è impostata per fare riferimento allo spazio dei nomi 'query' utilizzando Namespace().Ogni script di esecuzione completa crea la propria variabile chiamata ns nel proprio spazio dei nomi qui, ma ognuno di questi verrà impostato per fare riferimento allo stesso spazio dei nomi "query".
Ri: Esegui query in background, attendi che vengano completate e fai riferimento ad esse nello script JSL rimanenteInnanzitutto, grazie per questo script. Utilizzo degli spazi dei nomi, creazione di script di query SQL, verifica dell'esecuzione, fornire feedback sullo stato, gestire i risultati; questo script racchiude molti insegnamenti in poche righe di JSL.Posso seguirne la maggior parte, ma Non ho molta esperienza nella definizione e nell'utilizzo degli spazi dei nomi, quindi ho una domanda:
Nella seconda riga dello script, ns È definito come :
ns = new namespace( "queries" );
Quindi sembra ns viene ridefinito nelle istruzioni Run Background():
sql_query2 << Run Background( OnRunComplete(
ns = namespace( "queries" );
ns:dt2 = queryResult;
ns:query2isdone = 1;
) );
Lo spazio dei nomi all'interno di sql_query1 e 2 è lo stesso spazio dei nomi di quello definito all'inizio dello script, sembra che dovrebbe esserlo, oppure è uno spazio dei nomi locale all'istruzione della query a causa di Nomi predefiniti qui(1) dichiarazione all'inizio? Perché lo fa ns deve essere definito all'interno dell'istruzione Run Background()?
Grazie ancora per un pezzo di codice semplice, chiaro e bellissimo.
Ri: Esegui query in background, attendi che vengano completate e fai riferimento ad esse nello script JSL rimanentecomunque, un bel pezzo di codice a cui fare riferimento in un punto stretto. 
Ri: Esegui query in background, attendi che vengano completate e fai riferimento ad esse nello script JSL rimanenteCIAO @Byron_JMP ,
Sono d'accordo che se l'obiettivo è verificare lo stato delle query eseguite in modo interattivo, un utente non dovrebbe cercare oltre il Query Builder.Questa finestra di stato aveva lo scopo di dimostrare le parti del lavoro con le query che gli utenti avevano difficoltà a trovare con semplici ricerche sul Web, come fare riferimento ai risultati in uno script dopo averlo completato. Ad essere sincero, ricordo di aver avuto difficoltà a trovare un esempio minimo.Sono sicuro che ci sia un caso d'uso migliore là fuori...
Ri: Esegui query in background, attendi che vengano completate e fai riferimento ad esse nello script JSL rimanentesembra un'idea di progetto davvero intrigante.
Volevo solo notare che in Query Builder è presente una scheda di avanzamento in cui posso vedere quante query sono in esecuzione e il loro avanzamento. Forse questo sarebbe un modo per creare script per la piattaforma di creazione delle query per visualizzare queste informazioni anziché provare a ottenerle da zero?