问题
您希望在后台运行查询以防止用户界面冻结,或者您希望同时运行多个查询然后合并结果。 有时很难将您需要的所有功能都放在后台查询的“运行完成”脚本中。
解决方案
每个查询都将结果保存在所有脚本都可以访问的新命名空间中(查询和原始脚本)。原始脚本在继续之前不断检查结果。
//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 );首先,感谢您提供此脚本。 使用命名空间,编写 SQL 查询脚本,测试它们是否完成,提供状态反馈,管理结果;该脚本将大量教学内容打包到几行 JSL 中。我可以关注大部分内容,但是我没有太多定义和使用命名空间的经验,所以我有一个问题:
在脚本的第二行, ns是定义为:
ns = new namespace( "queries" );
然后好像ns在 Run Background() 语句中重新定义:
sql_query2 << Run Background( OnRunComplete(
ns = namespace( "queries" );
ns:dt2 = queryResult;
ns:query2isdone = 1;
) );
sql_query1 & 2 中的命名空间是否与脚本开头定义的命名空间相同,似乎必须是,或者它是查询语句的本地命名空间,因为名称默认为此处(1)开头的声明? 为什么ns需要在 Run Background() 语句中定义吗?
再次感谢您提供了一段简单、清晰、漂亮的代码。
尽管如此,还是有一些不错的代码可以在紧要关头参考。 
你好@Byron_JMP ,
我同意如果目标是检查以交互方式运行的查询的状态,那么用户应该只看查询生成器。此状态窗口旨在演示处理用户无法通过简单的 Web 搜索找到的查询的部分内容,例如完成后在脚本中引用结果。 老实说,我记得很难想出一个最小的例子。我敢肯定那里有更好的用例......
这听起来像是一个非常有趣的项目想法。
我只想指出,在查询生成器中,有一个进度选项卡,我可以在其中查看正在运行的查询数量及其进度。 也许这将是一种编写查询构建器平台脚本以显示此信息而不是尝试从头开始获取它的方法?