문제
사용자 인터페이스가 고정되지 않도록 백그라운드에서 쿼리를 실행하거나 동시에 여러 쿼리를 실행한 다음 결과를 결합하려고 합니다. 때로는 백그라운드 쿼리의 '실행 완료' 스크립트에 필요한 모든 기능을 넣는 것이 어렵습니다.
해결책
각 쿼리는 모든 스크립트(쿼리 및 원본 스크립트)가 액세스할 수 있는 새 네임스페이스에 결과를 저장합니다.원본 스크립트는 계속 진행하기 전에 결과를 계속 확인합니다.
//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 내의 네임스페이스가 스크립트 시작 부분에 정의된 것과 동일한 네임스페이스입니까, 그래야 할 것 같거나, 이름 기본값은 Here(1) 처음에 진술? 왜 ns Run Background() 문 내에서 정의해야 합니까?
간단하고 명료하며 아름다운 코드에 다시 한 번 감사드립니다.
여전히 좁은 공간에서 참조할 수 있는 좋은 코드입니다. : )
안녕 @Byron_JMP ,
목표가 대화식으로 실행되는 쿼리의 상태를 확인하는 것이라면 사용자는 쿼리 빌더 이상을 보지 않아야 한다는 데 동의합니다.이 상태 창은 완료된 후 스크립트에서 결과를 참조하는 것과 같이 사용자가 간단한 웹 검색으로 찾기 어려웠던 쿼리 작업 부분을 보여주기 위한 것입니다. 솔직히 말해서 최소한의 예를 생각해내는 데 어려움을 겪었던 기억이 납니다.더 나은 사용 사례가 있을 거라 확신합니다...
이것은 정말 흥미로운 프로젝트 아이디어처럼 들립니다.
쿼리 작성기에는 실행 중인 쿼리 수와 진행 상황을 볼 수 있는 진행률 탭이 있다는 점을 알고 싶었습니다. 이 정보를 처음부터 얻으려고 하지 않고 이 정보를 표시하도록 쿼리 빌더 플랫폼을 스크립팅하는 방법이 될 수 있습니까?