cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
New to using JMP? Hit the ground running with the Early User Edition of Discovery Summit. Register now, free of charge.
Register for our Discovery Summit 2024 conference, Oct. 21-24, where you’ll learn, connect, and be inspired.
Choose Language Hide Translation Bar
UEJ
UEJ
Level II

How to run multiple SQL queries in parallel, wait for fnish, and get list of datatables

Hi,

 

I would like to have a function, that (i) runs multiple SQL queries in background (connection and sql statements from string lists with arbitrary lengths), (ii) waits until all queries are finished, and (iii) returns a list of datatables. Please find my code below. I don't know how to gather the data tables correctly.

 

Thank you in advance.

 

Run_SQL_Queries = Function({o_connections, o_sqls},  
	i_dts = List();

	For(i_counter = 1, i_counter <= N Items(o_connections), i_counter++,  
		i_dt = Empty();
		i_connection = o_connections[i_counter];
		i_sql = o_sqls[i_counter];

		query = New SQL Query(Connection(i_connection), Custom SQL(i_sql)) << Run Background(OnRunComplete(i_dt = queryResult));
		Insert Into(i_dts, i_dt);
	);
	Return(i_dts);
);
1 ACCEPTED SOLUTION

Accepted Solutions
mmarchandTSI
Level V

Re: How to run multiple SQL queries in parallel, wait for fnish, and get list of datatables

I've been doing something similar for a while.  I run multiple queries simultaneously and then perform operations on the tables.  I have adapted my solution for your application.  It's not pretty, but I have tried many, many other ways in JMP, and nothing else has accomplished what I wanted.

 

Names Default To Here( 1 );
o_connections = {....Connection List....};
o_sqls = {....Query List....};
::i_dts = {};
Run_SQL_Queries = Function( {o_connection, o_sql, i_counter},
	{Default Local},
	Eval(
		Eval Expr(
			Expr(
				Parse( "::i_dt" || Char( i_counter ) || " = Empty()" )
			);
			New SQL Query( Connection( o_connection ), Custom SQL( o_sql ) ) << Run Background(
				OnRunComplete(
					Expr(
						Parse( "::i_dt" || Char( i_counter ) || " = QueryResult;" )
					);
					Insert Into( ::i_dts, QueryResult )
					;
				)
			);
		)
	)
);
For( i=1, i<=N Items(o_connections), i++, Run_SQL_Queries( o_connections[i], o_sqls[i], i ) );
For( i = 1, i <= N Items( o_connections ), i++,
	Eval( Parse( "While(!Is Scriptable(::i_dt" || Char( i ) || "), Wait(.5))" ) )
);
Show( ::i_dt1, ::i_dt2, ::i_dts );

View solution in original post

3 REPLIES 3
jthi
Super User

Re: How to run multiple SQL queries in parallel, wait for fnish, and get list of datatables

I'm not sure if you can build such a function in JMP. You might have to use << OnRunComplete within your << Run Background and perform whatever you are doing, after all queries are ready, using that.

-Jarmo
ErraticAttack
Level VI

Re: How to run multiple SQL queries in parallel, wait for fnish, and get list of datatables

Unfortunately JMP only provides a single execution thread for JSL.  For my company I get around this limitation and do exactly what you're wanting to do by using a persistent Python session.  I launch the Python session from JMP, which has a hook for when the STDOUT buffer is not empty, and in Python I start a localhost server and wait for commands.  Then in JMP I can connect to the localhost server and send messages.  Python will then, in parallel, complete the assigned tasks (whether it's SQL or file-transfers or anything needed) and have special print statements for when complete, thus closing the loop and allowing JMP to know when the queries are completed.

 

For SQL I have Python save the results in a temporary file then JMP can simply read the file.

 

It is a little round-about, but not too much more difficult than if JMP provided a means for concurrency or asynchronous execution.

 

This works quite well and the slowdown due to IPC is not noticeable.

Jordan
mmarchandTSI
Level V

Re: How to run multiple SQL queries in parallel, wait for fnish, and get list of datatables

I've been doing something similar for a while.  I run multiple queries simultaneously and then perform operations on the tables.  I have adapted my solution for your application.  It's not pretty, but I have tried many, many other ways in JMP, and nothing else has accomplished what I wanted.

 

Names Default To Here( 1 );
o_connections = {....Connection List....};
o_sqls = {....Query List....};
::i_dts = {};
Run_SQL_Queries = Function( {o_connection, o_sql, i_counter},
	{Default Local},
	Eval(
		Eval Expr(
			Expr(
				Parse( "::i_dt" || Char( i_counter ) || " = Empty()" )
			);
			New SQL Query( Connection( o_connection ), Custom SQL( o_sql ) ) << Run Background(
				OnRunComplete(
					Expr(
						Parse( "::i_dt" || Char( i_counter ) || " = QueryResult;" )
					);
					Insert Into( ::i_dts, QueryResult )
					;
				)
			);
		)
	)
);
For( i=1, i<=N Items(o_connections), i++, Run_SQL_Queries( o_connections[i], o_sqls[i], i ) );
For( i = 1, i <= N Items( o_connections ), i++,
	Eval( Parse( "While(!Is Scriptable(::i_dt" || Char( i ) || "), Wait(.5))" ) )
);
Show( ::i_dt1, ::i_dt2, ::i_dts );