問題
您希望在後台運行查詢以防止用戶界面凍結,或者您希望同時運行多個查詢然後合併結果。 有時很難將您需要的所有功能都放在後台查詢的“運行完成”腳本中。
解決方案
每個查詢都將結果保存在所有腳本都可以訪問的新命名空間中(查詢和原始腳本)。原始腳本在繼續之前不斷檢查結果。
//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 搜索找到的查詢的部分內容,例如完成後在腳本中引用結果。 老實說,我記得很難想出一個最小的例子。我敢肯定那裡有更好的用例......
這聽起來像是一個非常有趣的項目想法。
我只想指出,在查詢生成器中,有一個進度選項卡,我可以在其中查看正在運行的查詢數量及其進度。 也許這將是一種編寫查詢構建器平台腳本以顯示此信息而不是嘗試從頭開始獲取它的方法?