Swap Named Query in Expression

I am trying to swap between two different named queries for a dataset based on a tag value.
So I have a Named Query binding on a vision screen that populates a dataset and I need to be able to change which named query is running based on a tag value. I have attempted to use an expression to accomplish this however I havent had any luck getting it to work and cant seem to find any documentation on if it is even possible, I am leaning towards it is not but I wanted to make a post and ask in case I have missed something.
I know it would be possible to do this through scripting like this however that isnt an option on the binding (InternalProperty binding):

system.db.runNamedQuery("QueryName", {params})

and this is the expression version I have tried but it always returns that an illegal character is in the expression as the dot between system and db

if({[default]tag} = -2, system.db.runNamedQuery("Query1",{}), system.db.RunNamedQuery("Query2",{"param":uid}))

I don't understand why it wouldn't be possible. If you have {[default]tag} as a root container property (or just as a custom property somewhere) you can run propertyChange script on it and use that.

if event.propertyName == 'myTag':
    if event.newValue == -2:
        system.db.runNamedQuery("Query1",{})
    else: 
        system.db.RunNamedQuery("Query2",{"param":uid})

Though you could also handle this in a gateway tag change event. When the tag you care about changes you can do your logic there and assign the result to a dataset tag.

I suppose you could probably do this in a run script. Maybe something like

def runAppropriateNQ(tagValue, uid):
    if tagValue == -2:
        return system.db.runNamedQuery("Query1",{})
    else:
        system.db.runNamedQuery("Query2",{"param":uid})

and then your expression would be
runScript('someProjLibrary.runAppropriateNQ',0,{SomePath.To.TagValue}, {SomePath.To.uid})

and this would return an appropriate dataset. However to use runscript you can't use keyword arguments so I know that your uid doesn't matter for your first named query - you still need to feed something in.

I see where you're going with this but I dont understand how I would pass that to my internal property. Its a Named Query binding and as far as I can tell there is no way of binding the named query in the script into the Named Query path of the Internal Property.
image

My script looks something like this currently:

if event.propertyName == 'UserChoice':
	if event.newValue == -2:
        system.db.runNamedQuery("Query1",{})
		do stuff here
			
		for row in jobs:
			if row['jnum'] == jid:
				do more stuff here
				break
	else:
		system.db.runNamedQuery("Query2",{params here})
		do stuff here
				
		for row in jobs:
			if row['jnum'] == jid:
				do more here
				break

Oh ok this is inside a template. Shouldn’t be a problem as the propertyChange works on them identically.

I don’t see why you couldn’t do something like

if event.propertyName == 'UserChoice':
	if event.newValue == -2:
        jobs = system.db.runNamedQuery("Query1",{})
		do stuff here
			
		for row in jobs:
			if row['jnum'] == jid:
				do more stuff here
				break
	else:
		jobs = system.db.runNamedQuery("Query2",{params here})
		do stuff here
				
		for row in jobs:
			if row['jnum'] == jid:
				do more here
				break
    
    event.source.IncompleteJobs = jobs

But this would mean there should be no binding on IncompleteJobs.

So its possible to parse through a dataset table without it actually being visible on any binding or table component? It can just exist as code like that?

Also if it matters here is more of the code, I had trimmed it to make it easier as I wasnt sure it mattered in the post but as soon as you put the jobs = I noticed a possible issue:

if event.propertyName == 'UserChoice':
	if event.newValue == -2:
		system.db.runNamedQuery("Query1",{})
		jid = event.source.JobNum
		jobs = system.dataset.toPyDataSet(event.source.IncompleteJobs)
			
		for row in jobs:
			if row['jnum'] == jid:
				do not important things here
				break
	else:
		system.db.runNamedQuery("Query2",{params here})
		jid = event.source.StationNum
		jobs = system.dataset.toPyDataSet(event.source.IncompleteJobs)
		do not important things here
				
		for row in jobs:
			if row['jnum'] == jid:
				do not important things here
				break

You can just have a raw dataset as a custom property and not do anything with it.

But if you want to show it on table you can just bind to the internal property -

One thing with your code though is you never assign the dataset to a variable so you can’t ever assign it to your internal property or parameter or whatever.

So instead of

system.db.runNamedQuery("Query2",{params})

It should be

# ds = dataset
ds = system.db.runNamedQuery("Query2",{params})
#Do stuff with ds
event.source.IncompleteJobs = ds

and then you can parse the dataset variable ds, modify it, update, whatever, before assigning it to a property (presumably the same property your table data is bound too - I am assuming the IncompleteJobs property).

Just thought of an easier way that may be better for you.

You can also just always query both datasets. Then in your table data expression you figure out which one to use.

So perhaps a two internal properies like

namedQuery1 - Named Query binding to NamedQuery1 with no params
namedQuery2 - Named Query binding to NamedQuery2 with params

and then your table.data could look like

if(# SOME CONDITION HERE,
{path.to.namedQuery1},
{path.to.namedQuery2})

May be slightly inefficient since you’re always calling both named queries regardless of the situation but it does let you stick to doing all of this strictly with properties and expressions.

1 Like

I cannot believe I didn't think of this. It works exactly as I needed!

1 Like