Exécutez des requêtes en arrière-plan, attendez qu'elles se terminent et référencez-les dans le script JSL restantProblème
Vous souhaitez exécuter une requête en arrière-plan afin que l'interface utilisateur ne se fige pas, ou vous souhaitez exécuter plusieurs requêtes en même temps, puis combiner les résultats. Parfois, il est difficile de mettre toutes les fonctionnalités dont vous avez besoin dans le script "on run complete" des requêtes en arrière-plan.
La solution
Chaque requête enregistre les résultats dans un nouvel espace de noms auquel tous les scripts peuvent accéder (les requêtes et le script d'origine).Le script d'origine continue de vérifier les résultats avant de continuer.
//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(
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(
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 );Vous souhaitez exécuter des requêtes en arrière-plan, mais vous devez interagir avec les résultats.Cette méthode permet à plusieurs requêtes en arrière-plan de se terminer avant d'interagir avec les résultats.
UtilitairesRe : Exécutez des requêtes en arrière-plan, attendez qu'elles se terminent et référencez-les dans le script JSL restantTout d'abord, merci pour ce scénario. Utilisation d'espaces de noms, scripts de requêtes SQL, test s'ils sont terminés, fournir un retour d'information sur l'état, gérer les résultats ; ce script contient beaucoup d'enseignements dans quelques lignes de JSL.Je peux en suivre la majeure partie, mais Je n'ai pas beaucoup d'expérience dans la définition et l'utilisation des espaces de noms, j'ai donc une question :
Dans la deuxième ligne du script, ns est défini comme :
ns = new namespace( "queries" );
Il semble alors ns est redéfini dans les instructions Run Background() :
sql_query2 << Run Background( OnRunComplete(
ns = namespace( "queries" );
ns:dt2 = queryResult;
ns:query2isdone = 1;
) );
L'espace de noms dans sql_query1 & 2 est-il le même espace de noms que celui défini au début du script, il semble qu'il devrait l'être, ou s'agit-il d'un espace de noms local à l'instruction de requête en raison de la Noms par défaut ici(1) déclaration au début? Pourquoi ns doivent être définis dans l'instruction Run Background() ?
Merci encore pour un morceau de code simple, clair et beau.
Re : Exécutez des requêtes en arrière-plan, attendez qu'elles se terminent et référencez-les dans le script JSL restantencore, un bon morceau de code à référencer dans un endroit difficile. : )
Re : Exécutez des requêtes en arrière-plan, attendez qu'elles se terminent et référencez-les dans le script JSL restantSalut @Byron_JMP ,
Je suis d'accord si l'objectif est de vérifier l'état des requêtes exécutées de manière interactive, alors un utilisateur ne doit pas chercher plus loin que le générateur de requêtes.Cette fenêtre d'état était destinée à montrer les parties de l'utilisation des requêtes que les utilisateurs avaient du mal à trouver avec de simples recherches sur le Web, comme le référencement des résultats dans un script une fois qu'il était terminé. Pour être honnête, je me souviens avoir eu du mal à trouver un exemple minimal.Je suis sûr qu'il existe un meilleur cas d'utilisation...
Re : Exécutez des requêtes en arrière-plan, attendez qu'elles se terminent et référencez-les dans le script JSL restantcela ressemble à une idée de projet vraiment intrigante.
Je voulais juste noter que dans Query Builder, il y a un onglet de progression où je peux voir combien de requêtes sont en cours d'exécution et leur progression. Peut-être que ce serait un moyen de scripter la plate-forme de création de requêtes pour afficher ces informations plutôt que d'essayer de les obtenir à partir de zéro ?