親愛なるみんな、
さまざまなソースからのデータが必要になり、それらを結合することがよくあります。 一部のクエリには時間がかかる場合があるため、バックグラウンドでいくつかのクエリを開始し、最後にデータを結合するスクリプトを作成しました。 ただし、すべてのクエリがいつ終了し、いつ結果の処理を開始するかをトリガーするのはそれほど簡単ではありません。 以下のスクリプトでは 2 つのアプローチ (「OnRunComplete」によるフラグの設定と結果テーブルの存在のテスト) をテストしました。 それらはかなり機能しますが、さらに良い方法があるかもしれないと思います。
問題の 1 つは、クエリのいずれかがテーブルを提供しない場合、ループが無限に実行されることです。 もう 1 つの問題は、クエリがまだアクティブであるかどうかをスクリプトが実際には制御していないことです。
現在、スクリプトはデバッグ モードに設定されており、この動作をテストするためにデータベース接続は必要ありません。
改善のアイデアはありますか? ありがとう、BR
// Purpose:
// Start two database Queries (from different sources) in parallel and in background
// Wait for queries to finish
// and combine result
// JMP 15.0 Win10
//
// Details:
// After both queries are started in background
// a loop is started, that queries when both tables are existing
// In a previous version I worked with setting a flag ("OnRunComplete( B_QUERY_FINISHED = 1 )")
//
// Problem:
// A better solution would be to test, whether DB query is still running, but how?
// If the database query ends unexpectedly (by passing no table), the loop runs infinetely
Names Default To Here( 1 );
Clear Log();
// debug_mode: 0 - query from database / 1 - make table
// for database query the connectionstring must be correct
debug_mode = 1;
A_QUERY_FINISHED = 0;
B_QUERY_FINISHED = 0;
A_NAME = "A_Table";
B_NAME = "B_Table";
// new function to check whether background query is finished (= table does exists)
table_exists = Function( {table_name},
Names Default To Here( 1 );
table_lst = Get Data Table List();
table_name_lst = {};
For( i = 1, i <= N Items( table_lst ), i++,
Insert Into( table_name_lst, table_lst[i] << get name() )
);
Return( If( Contains( table_name_lst, table_name ) > 0, 1, 0 ) );
);
If( table_exists( A_NAME ) | table_exists( B_NAME ) ,
Throw( eval insert ("^A_NAME^ or ^B_NAME^ open! Please close " ))
);
// Define query
sql_str = "Select * from dual";
A_sql_str = sql_str;
B_sql_str = Substitute( sql_str, "A_scheme", "B_scheme" );
// Database query expression in backgroud
nsqlq_A_expr = Expr(
New SQL Query( Connection( "ODBC:DSN=XXX;DBQ=YYY;" ), QueryName( A_Name ), CustomSQL( A_sql_str ) ) <<
Run Background( OnRunComplete( A_QUERY_FINISHED = 1 ) )
);
nsqlq_B_expr = Expr(
New SQL Query( Connection( "ODBC:DSN=ZZZ;DBQ=AAA;" ), QueryName( B_Name ), CustomSQL( B_sql_str ) ) <<
Run Background( OnRunComplete( B_QUERY_FINISHED = 1 ) )
);
// Create table expression for Debugging
A_expr = Expr(
New Table( "A_Table", Add Rows( 1 ), Compress File When Saved( 1 ), New Column( "DUMMY", Character, "Nominal", Set Values( {"X"} ) ) )
);
B_expr = Expr(
New Table( "B_Table", Add Rows( 1 ), Compress File When Saved( 1 ), New Column( "DUMMY", Character, "Nominal", Set Values( {"X"} ) ) )
);
// start queries only in case of no debug_mode
If( debug_mode == 0,
Eval( nsqlq_A_expr );
Eval( nsqlq_B_expr );
);
start_time = Tick Seconds();
timestep = 1;
While( (table_exists( A_NAME ) & table_exists( B_NAME )) != 1,
Wait( timestep );
time_running = Round( Tick Seconds() - start_time, 0 );
Print( "waiting " || Char( time_running ) );
Show( table_exists( A_NAME ) );
Show( table_exists( B_NAME ) );
// For debugging only: create Table A after 5 seconds and Table B after 10 seconds
If( debug_mode == 1,
If( time_running > 5 & !table_exists( A_NAME ),
Eval( A_expr )
);
If( time_running > 10 & !table_exists( B_NAME ),
Eval( B_expr )
);
);
);
Wait( 1 );
Print( "Queries Finished" );
end_time = Tick Seconds();
Print( "Duration: " || Char( Round( end_time - start_time ) ) );
// concatenate
Try( Data Table( A_Name ) << Concatenate( Data Table( B_Name ), Append to first table ), Throw( Print( "Concatenate error" ) ) );
// Close( Data Table( B_Name ), nosave );
Data Table( A_Name )<< set name("Result Table");
Print( "Concatenating finished, script end " );これと同じ問題が発生したとは思えませんが、引き続き問題が発生する場合は、エラーを含むログ出力を投稿していただけますか、修正できる場合はサンプル スクリプトを更新する方法を教えていただけますか?
環境設定に ODBC 設定があり、それが私にとって同様の不正行為を引き起こしました。 「可能であればバックグラウンドでクエリを実行する」オプションがチェックされている場合は、チェックを外してスクリプトを再試行してください。 これを行うには速度と安定性のトレードオフがあると思いますが、まだ試していない場合は試してみる価値があります。

ありがとう@ihあなたの解決策としては、それは素晴らしく、よくプログラムされているので、それを使って作業してみます。
最初のテストでは、参照が (まだ) 有効ではなかったために、まだタイミングの問題 (おそらく) が見られました。
ステートメント「onRunComplete」に数秒間の待機を導入すると機能しましたが、解決策ではありません。
それが、私が以前、使用可能なテーブルを参照する前にクエリを実行することにした理由だと思います。 さらにテストしてみます。