Mule DB connector parameterized query - database

This is my first time experience with Mule & trying to define a flow with DB connector. I am defining a parameterized simple select query with 3 parameters but somehow not able to figure it out. Even I tried putting entire/partial query in Variable before passing the variable value to query but could not succeed. Any help is highly appreciated.
select * from employees where employee_country='UK' limit 1,10;
Here UK,1 & 10 are dynamic values which will come from UI as below, http://localhost:9090/employee?country=UK&start=1&limit=10
My try:
select * from employees where employee_country=#[message.inboundProperties.'http.query.params'.country] limit #[message.inboundProperties.'http.query.params'.start],#[message.inboundProperties.'http.query.params'.limit]
Thanx, -Swapnil

You are trying to create a dynamic query. For a parameterised query, you should separate the parameter values with placeholders. Parameterized won't replace expressions.
Here is the difference between the two options:
<db:select config-ref="DBConfig" doc:name="Database">
<db:parameterized-query><![CDATA[select * from employees where employee_country= :country limit 1,10;]]></db:parameterized-query>
<db:in-param name="country" type="VARCHAR" value="#[message.inboundProperties.'http.query.params'.country]" />
</db:select>
Dynamic:
<db:select config-ref="DBConfig" doc:name="Database">
<db:dynamic-query><![CDATA[select * from employees where employee_country=#[message.inboundProperties.'http.query.params'.country] limit #[message.inboundProperties.'http.query.params'.start],#[message.inboundProperties.'http.query.params'.limit]]]></db:dynamic-query>
</db:select>
Here is the documentation explaining the difference:
https://docs.mulesoft.com/mule-runtime/3.7/database-connector#query-types
Parameterized is the recommended approach as the disadvantage of using dynamic query statements is security as it leaves the statement open for SQL injection.

In real time you might need these values in the flow .To reuse them capture via flow variables.
When we have dynamic value that are coming in query params..capture it via variable name originalQueryParams
#[message.inboundProperties.'http.query.params']
Use groovy script to capture those variables and seperate them via set invocation properties ..
def inputRequest = message.getInvocationProperty('originalQueryParams');
message.setInvocationProperty('country',inputRequest.country);
return payload;
Now Country is you flow variable and pass it in the query .
select * from employees where employee_country = '#[flowVars.country]'
Hope this helps

Related

MS Access, use query name as field default value

My department uses a software tool that can use a custom component library sourced from Tables or Queries in an MS Access database.
Table: Components
ID: AutoNumber
Type: String
Mfg: String
P/N: String
...
Query: Resistors
SELECT Components.*
FROM Components
WHERE Components.Type = "Resistors"
Query: Capacitors
SELECT Components.*
FROM Components
WHERE Components.Type = "Capacitors"
These queries work fine for SELECT. But when users add a row to the query, how can I ensure the correct value is saved to the Type field?
Edit #2:
Nope, can't be done. Sorry.
Edit #1:
As was pointed out, I may have misunderstood the question. It's not a wonky question after all, but perhaps an easy one?
If you're asking how to add records to your table while making sure that, for example, "the record shows up in a Resistors query if it's a Resistor", then it's a regular append query, that specifies Resisitors as your Type.
For example:
INSERT INTO Components ( ID, Type, Mfg )
SELECT 123, 'Resistors', 'Company XYZ'
If you've already tried that and are having problems, it could be because you are using a Reserved Word as a field name which, although it may work sometimes, can cause problems in unexpected ways.
Type is a word that Access, SQL and VBA all use for a specific purpose. It's the same idea as if you used SELECT and FROM as field or table names. (SELECT SELECT FROM FROM).
Here is a list of reserved words that should generally be avoided. (I realize it's labelled Access 2007 but the list is very similar, and it's surprisingly difficult to find an recent 'official' list for Excel VBA.)
Original Answer:
That's kind a a wonky way to do things. The point of databases is to organize in such a way as to prevent duplication of not only data, but queries and codes as well
I made up the programming rule for my own use "If you're doing anything more than once, you're doing it wrong." (That's not true in all cases but a general rule of thumb nonetheless.)
Are the only options "Resistors" and "Capacitors"? (...I hope you're not tracking the inventory of an electronics supply store...) If there are may options, that's even more reason to find an alternative method.
To answer your question, in the Query Design window, it is not possible to return the name of the open query.
Some alternative options:
As #Erik suggested, constrain to a control on a form. Perhaps have a drop-down or option buttons which the user can select the relevant type. Then your query would look like:
SELECT * FROM Components WHERE Type = 'Forms![YourFormName]![NameOfYourControl]'
In VBA, have the query refer to the value of a variable, foe example:
Dim TypeToDel as String
TypeToDel = "Resistor"
DoCmd.RunSQL "SELECT * FROM Components WHERE Type = '" & typeToDel'"
Not recommended, but you could have the user manually enter the criteria. If your query is like this:
SELECT * FROM Components WHERE Type = '[Enter the component type]'
...then each time the query is run, it will prompt:
Similarly, you could have the query prompt for an option, perhaps a single-digit or a code, and have the query choose the the appropriate criteria:
...and have an IF statement in the query criteria.
SELECT *
FROM Components
WHERE Type = IIf([Enter 1 for Resistors, 2 for Capacitors, 3 for sharks with frickin' laser beams attached to their heads]=1,'Resistors',IIf([Enter 1 for Resistors, 2 for Capacitors, 3 for sharks with frickin' laser beams attached to their heads]=2,'Capacitors','LaserSharks'));
Note that if you're going to have more than 2 options, you'll need to have the parameter box more than once, and they must be spelled identically.
Lastly, if you're still going to take the route of a separate query for each component type, as long as you're making separate queries anyway, why not just put a static value in each one (just like your example):
SELECT * FROM Components WHERE Type = 'Resistor'
There's another wonky answer here but that's just creating even more duplicate information (and more future mistakes).
Side note: Type is a reserved word in Access & VBA; you might be best to choose another. (I usually prefix with a related letter like cType.)
More Information:
Use parameters in queries, forms, and reports
Use parameters to ask for input when running a query
Microsoft Access Tips & Tricks: Parameter Queries
 • Frickin' Lasers

django query get rows where two columns difference is greater than a value

I have a table in my model including some feature and I want to execute select query like this in Django:
SELECT * FROM TABLE WHERE column1-column2 > 10000
I tried filter(), but after a little search I found out that I should use .annotate() and I changed my query to:
Account.objects.annotate(realcharge=(F('charge')-F('amount')), realcharge__lt=10000)
But i get this error:
'int' object has no attribute 'resolve_expression'
How should I write my query?
my django version is 1.11.
I don't know if you still need an answer, but you could try the .filter() method after the call to .annotate(), like this:
# Note: I split this query in 2 lines for better readability
qs = Account.objects.annotate(realcharge=(F('charge')-F('amount')))
qs = qs.filter(realcharge__lt=10000)

Mule Database Connector Multiple Queries

I am running multiple select queries and I want them to run one after the other.
In this example, I select account numbers then use those numbers in the following query. Will the queries run consecutively one after the other i.e. next query only runs after the previous query has finished. Do I need to wrap them in a composite-source and wrap them in a transaction? What would that look like?
<flow name="PopulateAccount">
<db:select config-ref="dsConfig" doc:name="Get Account ID">
<db:paramterized-query><![CDATA[
SELECT ACC_NUM....
</db:select>
<custom-transformer class="com.vf.ListTransformer">
<set-session-variable variableName="messageID" value="#[payload]"
doc:name="Set Account IDs"/>
<!-- The next query depends on the Account IDS from
previous results in the session variable -->
<db:select config-ref="dsConfig" doc:name="Get Account Detail">
<db:paramterized-query><![CDATA[
SELECT ACC_NAME,....
</db:select>
<custom-transformer class="com.vf.AccountsTransformer">
<!-- More database operations --->
</flow>
Will the queries run consecutively one after the other
yes, as long as you do not take any measures to run them in parallel, like for example moving the database component in a separate flow and call it in a asynchronous way.
Do I need to wrap them in a composite-source
no, especially not if you use the result of the first query in the second query (like in your example)
and wrap them in a transaction
why? you are not inserting/updating anything in your example.
What would that look like?
just like in your example. the only thing i would change is the way how you store the result of your first query. although there is nothing wrong with using set-variable i prefer using a enricher to store result of a component in variable instead of changing the payload and setting the variable afterwards.
<flow name="testFlow">
<enricher target="#[flowVars.messageID]" doc:name="Message Enricher">
<db:select config-ref="MySQL_Configuration" doc:name="select ACC_NUM">
<db:parameterized-query><![CDATA[SELECT ACC_NUM ...]]></db:parameterized-query>
</db:select>
</enricher>
</flow>

Relational database structure design advice

This is a textual description of data for which I need to create a database design (using SQLite) for an application.
The application needs to keep a record of operations. Each operation has a Name and its list of parameters. Each parameter has its Name and a Value. However, the values of the parameters will change over the lifetime of the app (in fact the user will be able to changes them using GUI) and we want to keep a history of the values which a certain parameter has had. Furthermore, each operation can have multiple parameter sets. A parameter set is like an envelope which encompasses a set of parameter values (which all belong to the same operation) and gives this envelope a unique Number and a non-unique Description.
This is what I have so-far:
[Database model image][1]
The database model should allow me to perform these actions on the database data:
Show a list of operations - I know how to do this.
Show a list of parameters for a given operation - I know how to do this.
For a given operation, show all its parameters as columns and show the values of the parameters as rows - each row represents a different parameter value from the history of values. I'm stuck at this one.
For a given operation, show a list of all parameter sets which belong to that operation. I'm stuck at this one too.
For a given operation and for a given parameter set, get the latest values of its parameters. Stuck at this.
I'm not sure if I should re-work my database model or if I should look for proper SQL statements to accomplish the tasks above with the model that I have. Any help is greatly appreciated. Thank you.
EDIT 1
I have re-worked my database model according to a helpful advice from #Marek Herman. Thanks to that I am able to accomplish tasks 1) 2) 4).
Now I'm trying to accomplish 5) which should not be that difficult with the current database model. I have this SQL statement:
SELECT Parameter.ParameterIdentifier, ParameterValue.ParameterValue,
ParameterValueVersion.VersionNumber, ParameterValueVersion.ChangedOn
FROM ParameterValueVersion INNER JOIN
(((Operation INNER JOIN Parameter ON Operation.OperationPLC_ID = Parameter.OperationPLC_ID)
INNER JOIN ParameterSet ON Operation.OperationPLC_ID = ParameterSet.OperationPLC_ID)
INNER JOIN ParameterValue ON (ParameterSet.ID = ParameterValue.ParameterSetID) AND
(Parameter.ID = ParameterValue.ParameterID)) ON ParameterValueVersion.ID = ParameterValue.ParameterValueVersionID
WHERE (Operation.OperationPLC_ID=[opID] AND
ParameterSet.ParameterSetNumber=[parSetNum]);
where [opID] and [parSetNum] are the input parameters. This SQL statement actually only joins all these tables together on their PK->FK relationship: Operation, Parameter, ParameterSet, ParameterValue, ParameterValueVersion and filters the rows by specified OperationPLC_ID and ParameterSetNumber.
Here is an example of an output of this SQL statement. Each row shows a name of a parameter, its value, a version number of the value and date of change of that value. Some parameters only have one value (only one version -e.g., "OFFSET"). Some parameters have two values. For example "PREFILLING" has a value of "3" which was input on Oct 20, 2016 (and has a version number 1) and it also has a value of "3.5" which was input on Oct 21, 2016 and has a version number of 2. So I'd like to show only the latest versions of the values of the parameters. Any advice how to modify the SQL statement is much appreciated. Thank you.
EDIT 2
I guess I figured out how to perform 5). I had to study a bit how GROUP BY works. This did the trick:
SELECT Parameter.ParameterIdentifier, last(ParameterValue.ParameterValue) AS ParameterValue, last(ParameterValueVersion.ChangedOn) AS ChangedOn, max(ParameterValueVersion.VersionNumber) AS VersionNumber
FROM ParameterValueVersion INNER JOIN
(((Operation INNER JOIN Parameter ON Operation.OperationPLC_ID = Parameter.OperationPLC_ID)
INNER JOIN ParameterSet ON Operation.OperationPLC_ID = ParameterSet.OperationPLC_ID)
INNER JOIN ParameterValue ON (ParameterSet.ID = ParameterValue.ParameterSetID) AND
(Parameter.ID = ParameterValue.ParameterID)) ON ParameterValueVersion.ID = ParameterValue.ParameterValueVersionID
WHERE (((Operation.OperationPLC_ID)=[opID]) AND ((ParameterSet.ParameterSetNumber)=[parSetNum]))
GROUP BY Parameter.ParameterIdentifier
ORDER BY Parameter.ParameterIdentifier
Now I still need to figure out how to perform task no. 3. I'm gonna study the suggested COALESCE function. Thank you.
0) I would connect ParameterSet to Operation and Parameter and not to ParameterValue.
1) okay!
2) okay!
3) I think you can use the COALESCE() function to display the columns and then it should be possible to show all parameters with matching OperationID
4) you can do that if you do point #0
5) same as above I think

How exactly setQueryMode of VO works?

I am new to Oracle ADF and i am stuck in understanding concept of how queryMode works.
can some one please explain me following
--> what data will be in VO cache,EO cache when i do just vo.executeQuery()
--> what happens when i use setQueryMode() and does vo.executeQuery() with different modes like QUERY_MODE_SCAN_VIEW_ROWS,QUERY_MODE_SCAN_ENTITY_ROWS,QUERY_MODE_SCAN_DATABASE_TABLES|QUERY_MODE_SCAN_ENTITY_ROWS on the below table.
--> When we apply ViewCriteria with the above modes how it behaves.
lets take following table called InfoTable
Id|StartDate|EndDate|Country|Status
56|01-APR-16|31-DEC-16|US|A
57|01-APR-16|31-DEC-16|IND|A
58|14-APR-16|31-DEC-16|UK|N
Note:Here PrimarKey(id,StartDate,EndDate)
Can we visualize what data in EO,VO cache like data base tables?
Thanks in advance.
QueryMode determines how VOs works with data:
QUERY_MODE_SCAN_DATABASE_TABLES: always gets data from database (default mode);
QUERY_MODE_SCAN_VIEW_ROWS: takes data from existing rows without requerying them from database(in memory);
QUERY_MODE_SCAN_ENTITY_ROWS: uses entity cache (only for entity-based VOs)
Sorting:
When you invoking sorting method for QUERY_MODE_SCAN_DATABASE_TABLES, then your original sql-query changing by AdfBc engine to:
select *
from ([original select defined in your ViewObject])
order by field1;
In case of QUERY_MODE_SCAN_VIEW_ROWS sorting uses Comparable interface in memory;
Filtering:
Filtering process uses ViewCriteria, which also has queryMode:
CRITERIA_MODE_QUERY: uses Database to retrieve filter data. As in example of sorting AdfBc also dynamically surrounds your original query with external select with where clause and predicates adjusted by ViewCriteria:
select *
from ([original select defined in your ViewObject])
where field1=:field1 and field2 between :field2_start and :field2_end;
CRITERIA_MODE_CACHE: all data restrictions appears in memory.

Resources