問題
ユーザー インターフェイスがフリーズしないようにバックグラウンドでクエリを実行したい、または複数のクエリを同時に実行して結果を結合したい。 バックグラウンド クエリの「on run complete」スクリプトに必要なすべての機能を配置するのが難しい場合があります。
解決
各クエリは、すべてのスクリプト (クエリと元のスクリプト) がアクセスできる新しい名前空間に結果を保存します。元のスクリプトは、続行する前に結果をチェックし続けます。
//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 に詰め込んでいます。大体フォローできますが、名前空間の定義と使用の経験があまりないので、質問があります。
スクリプトの 2 行目で、 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() ステートメント内で定義する必要がありますか?
シンプルで明快で美しいコードをありがとう。
それでも、狭い場所で参照するのに適したコードです。 : )
やあ@バイロン_JMP 、
インタラクティブに実行されるクエリのステータスを確認することが目標である場合、ユーザーはクエリ ビルダー以外に目を向けるべきではないことに同意します。このステータス ウィンドウは、完了後にスクリプトで結果を参照するなど、ユーザーが単純な Web 検索では見つけにくいクエリの操作の一部を示すことを目的としていました。 正直なところ、最小限の例を思いつくのに苦労したことを覚えています。他にもっと良い使用例があると確信しています...
これは非常に興味深いプロジェクトのアイデアのように思えます。
クエリビルダーには、実行中のクエリの数とその進行状況を確認できる進行状況タブがあることに注意してください。 おそらく、これはクエリ ビルダー プラットフォームをスクリプト化して、この情報を最初から取得しようとするのではなく、この情報を表示する方法でしょうか?