Passing a List to an sql-component query - apache-camel

I'm having trouble to pass a list of string I'm getting back from my bean to my sql-component query to make a call to the database.
<bean ref="fo" method="transformTo(${body})" />
So in this upper line of code I'm taking data from the body that is an xml and transform it to json.
<bean ref="fot" method="getOTs(${body})" />
Then I'm extracting the part I want from the json and return a list of string (method signature) :
public List<String> getOTs(String jsonOTs)
Now the part that isn't working (I'm getting that one parameter is expected but there are a couple each time)
<to uri="sql:insert into dbo.table_example (OT) VALUES :#body;"/>
My goal is quite simple, retrieving a list of string from my bean (working) and making and an insert into query. I have only one parameter but multiple values. Example:
INSERT INTO table_name (column_list)
VALUES
(value_list_1),
(value_list_2),
...
(value_list_n);
Example taken from here

Bulk insert
For a bulk insert, you need to set the query parameter batch to true, this way, Camel will understand that you want to insert several rows in one batch.
Here is the corresponding to endpoint in your case:
<to uri="sql:insert into dbo.table_example (OT) VALUES (#)?batch=true"/>
Miscellaneous remarks
Actually, for all the use cases that you listed above, you have no need to explicitly refer to the body.
Indeed, in the case of a bean, you could only specify the method to invoke, Camel is able to inject the body as a parameter of your method and automatically converts it into the expected type which is String in your case.
Refers to https://camel.apache.org/manual/bean-binding.html#_parameter_binding for more details.
Regarding the SQL producer, assuming that you did not change the default configuration, the proper way is to rather use the placeholder that is # by default, Camel will automatically use the content of the body as parameters of the underlying PreparedStatement.
So you should retry with:
<to uri="sql:insert into dbo.table_example (OT) VALUES (#)"/>
If you really want to explicitly refer to the body in your query, you can rather use :#${body} as next:
<to uri="sql:insert into dbo.table_example (OT) VALUES (:#${body})"/>
Misuse of named parameter
If you only use #body as you did, Camel interprets it as a named parameter so it will try to get the value from the body if it is a map by getting the value of the key body otherwise it will try to get the value of the header body but in your case, there are no such values, therefore, you end up with an error of type
Cannot find key [body] in message body or headers to use when setting named
parameter in query [insert into developers (name) values :?body;] on the exchange

Related

Pass array as query parameter in Postman

I am trying to pass an array as query parameter in Postman.
I am calling DELETE method to delete a user from list of databases. It is expecting list of database names as array in the query parameter. When I pass as given below, I am getting error.
{"code":2,"message":"data_services must be an array and not empty"}
Please let me know, how can I pass an array as query parameter in Postman.
You need to create 2 keys with the same name and add postfix []
You can specify the parameter key multiple times with different values.
Don't use square brackets or numbers like an array in code.
This will result in a query string like so:
?data_services=somename&data_services=anothername
I mis-read the DELETE method. It was expecting array of databases in the body of the Http body section, instead of on query parameter section. I provided the array as given below and it got succeeded.
The below is the way, I passed array to Http request in the body section.
can you check below link it is useful for you
https://medium.com/#darilldrems/how-to-send-arrays-with-get-or-post-request-in-postman-f87ca70b154e

Can we count the number of query parameters passed through browser in Mule

I am trying to write a stored procedure which works dynamically. For example, If I pass three query parameters from the browser to the flow it should be assigned to the stored procedure and it should retrieve only the values from the database only for which the passed values. (Note: I am using select query in my stored procedure). I should be able to pass n number of query parameters. Could anyone assist me on this.
For your query on how to get the Query parameters key names:
Use the below expression to get the first query parameter key name. Change index value based on query parameter number.
#[message.inboundProperties.'http.query.params'.keySet().toArray()[0]]
See the below sample code that iterates over the query parameters and stores each query parameter key name into variable then prints it in logger.
<foreach collection="#[message.inboundProperties.'http.query.params'.keySet()]" doc:name="For Each">
<set-variable variableName="QueryPramKey" value="#[payload]" doc:name="Variable"/>
<logger message="--- Query param kay names: #[flowVars.QueryPramKey]" level="INFO" doc:name="Logger"/>
The query params are available as a Map, so you can just call .size():
message.inboundProperties['http.query.params'].size()

How to avoid in SQL to store an XML <option></option> like <option />?

When I try to store a XML in SQL than have an empty Element, SQL just change it and store it with only one tag for the element.
For Example the XML to store is:
<ROOT>
<FIRSTNAME>ROGER</FIRSTNAME>
<MIDDLENAME></MIDDLENAME>
</ROOT>
Then Sql stored it like
<ROOT>
<FIRSTNAME>ROGER</FIRSTNAME>
<MIDDLENAME />
</ROOT>
The sql update is just very simple:
UPDATE
SESIONESREPORTES
SET
SER_PARAMETROS = '
<ROOT>
<FIRSTNAME>ROGER</FIRSTNAME>
<MIDDLENAME></MIDDLENAME>
</ROOT>'
WHERE SER_ID=7
I need like this because I have some query that fails when a element is empty, you can see it here..
Merging many rows in a single
I don't think you can, looking at the following link:
XML Data Type and Columns
According to this (XML Storage Options Section):
The data is stored in an internal representation that preserves the
XML content of the data. This internal representation includes
information about the containment hierarchy, document order, and
element and attribute values. Specifically, the InfoSet content of the
XML data is preserved. For more information about InfoSet, visit
http://www.w3.org/TR/xml-infoset. The InfoSet content may not be an
identical copy of the text XML, because the following information is
not retained: insignificant white spaces, order of attributes,
namespace prefixes, and XML declaration.
So the internal storage will strip out all parts it deems unnecessary, the document goes on to state that if you need an exact copy of the XML document and not just the content, you should use either [n]varchar(max) or varbinary(max)
<MIDDLENAME></MIDDLENAME>
and
<MIDDLENAME/>
are equivalent; any XML parser will treat them identically - as an empty element. If your query fails on an empty element, it will fail on either of them. You'll need to either rewrite your query to handle empty elements, put some content in the <MIDDLENAME> element, or omit the element entirely (if your query can handle it's absence.)

WSO2 DSS - A way to expose single row / single column result as string

I'm using WSO2 DSS and I'm interested in how to expose a single row/column result of a query as a string, and not as an array entry.
So for example if I have query: Select 'test' as t From dual;
It will return only one row with one column, so I don't want the result to be enclosed in like below
<Entry>
<t>test</t>
</Entry>
instead I would like to have just
<t>test</t>
as a response.
Is such a thing possible with dss? what type of output mapping needs to be used in such a case?
In DSS you can add XSLT to extract the test from your response.
There is an field called XSLT Path in Result (output mapping) section. You can give the configuration registry path or governance registry path for that xslt to do that.

SQL Server "Optional" FreeText Search

I'm writing a search query in SQL Server 2005 for a discussion board. The proc takes several parameters, but most are "optional". There's one search field for Message Body, which I have a full text index on. Here's the problem..
If I pass in a value to search against with FreeText, the search works fine (thank you Microsoft). However, the message body field is optional, meaning that in my query, I want to handle a "search all". How can I default my query to just use any\all records regardless of the data held in my message body field?
I know this doesn't work, but if no value is returned for the message body parameter, Im looking for something like:
where (FREETEXT(msg.messagebody, '*'))
You could do something like:
select * from Products_CatalogProducts where (#keywords='*' or freetext(msg.messagebody,#keywords))
Assuming you passed in #keywords with a * if it's blank

Resources