여러분 모두에게,
나는 종종 다른 출처의 데이터가 필요하고 그것들을 결합합니다. 일부 쿼리는 시간이 오래 걸릴 수 있으므로 백그라운드에서 여러 쿼리를 시작하고 끝에 데이터를 결합하는 스크립트를 작성했습니다. 그러나 모든 쿼리가 완료되고 결과 처리를 시작할 때 트리거를 찾는 것은 그리 쉬운 일이 아닙니다. 아래 스크립트에서 두 가지 접근 방식("OnRunComplete"로 플래그 설정 및 결과 테이블의 존재 여부 테스트)을 테스트했습니다. 그들은 상당히 작동하지만 더 나은 방법이 있을 수 있다고 생각합니다.
한 가지 문제는 쿼리 중 하나가 테이블을 제공하지 않으면 루프가 무한히 실행된다는 것입니다. 또 다른 문제는 쿼리가 여전히 활성 상태인지 여부를 스크립트가 실제로 제어하지 않는다는 것입니다.
스크립트는 현재 디버그 모드로 설정되어 있으며 이 동작을 테스트하기 위해 데이터베이스 연결이 필요하지 않습니다.
개선을 위한 아이디어가 있습니까? 감사합니다. 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" 문에서 몇 초 동안 대기하는 방법을 도입한 다음 작동했지만 해결책은 아닙니다.
그래서 이전에 사용 가능한 테이블을 참조하기 전에 쿼리하기로 결정한 것 같습니다. 나는 그것을 더 테스트 할 것이다.