Section | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
...
There are two ways to disable the emit Null column featureattribute:
Add the dbconnector.emitNullColumns=false property to the dbconnector properties file for your installation.
OR add the emitNullColumns="false" attribute to the respective element in the configuration.xml file for your installation:
For example:
...
Code Block |
---|
<retrieve> <statement> SELECT id, tenant, role, de$cription FROM roles; </statement> </retrieve> |
The This workaround to avoid this error is to use is recommended - Use an 'as' clause in the query like this:
Code Block |
---|
<retrieve> <statement> SELECT id, tenant, role, de$cription as description FROM roles </statement> </retrieve> |
Stored Procedures
You can also execute stored procedures via the database connector. Here is an example of a mySql stored procedure.
Empty resultsets
The XML Schema generated by the dbconnector requires at least 1 row (minOccurs=1). When the resultset has no rows, the connector sends an empty string, i.e. invalid XML instance. This is because the attribute emptyStringForEmptyResultSet="true" is configured by default.
logs a warning to that effect. You may notice an error message similar to the image below in the debug console when testing your forms.
This behavior can be controlled by adding the queryset attribute emptyStringForEmptyResultSet with a value of false to the queryset in the configuration.xml file or by adding the property dbconnector.queryset.emptyStringForEmptyResultSet=false to the dbconnector.properties file.
Post/Put to the Database Connector from a Business Rule
The Database Connector supports URL parameters and JSON payload in POST/PUT requests. You can use http.post() and http.put() statements in a Live Forms business rule to send data to the frevvo Database Connector to insert/update records into your external database.
Use the http.post method to insert records into your database and use the http.put method to update existing records.
Let’s take a look at an example to explain this.
Create a form from the Database Connector schema (productDetails) to insert a record into the products table in an external database named classicmodels. We have added a Trigger control to make testing the rules easier. The MySQL classicmodels database has a table named products. When we execute the rule in our frevvo form, we want to insert a record into this database table.
Here is an image of the form:
This query is included in the configuration.xml.
Code Block |
---|
</query>
<query name="productDetails" autocreate="true">
<retrieve>
<!--maps to HTTP GET -->
<statement> SELECT * from Products order by productName </statement>
</retrieve>
<create>
<statement>INSERT into Products (productCode,productName,productLine,productScale,productVendor,productDescription,quantityInStock,buyPrice,MSRP)
VALUES ('{productCode}','{productName}','{productLine}','{productScale}','{productVendor}','{productDescription}',{quantityInStock},{buyPrice},{MSRP})</statement>
</create>
</query>
|
There are 3 ways to insert/update a record in your external database by passing data to the Database Connector.
A Doc URI - this is the simplest way but the Doc URI is only executed when a form is submitted or a flow has completed it’s final step. When the user submits the form or completes the flow, the URI will be executed with the POST method selected from the dropdown. The database connector will execute the Insert operation identified by the URI.
Code Block http://localhost:8082/database/BIRT/productDetails
A business rule to pass the data to the database connector post using URL query parameters. When the user clicks on the Trigger control, this rule will run and the database connector will execute the Insert operation identified by the URL in the productDetails query in the configuration.xml file..
Code Block language js if (trigger.clicked) { var PostURL = 'http://localhost:8082/database/BIRT/productDetails?productCode=' + productCode.value + '&productName=' + productName.value + '&productLine=' + productLine.value + '&productScale=' + productScale.value + '&productVendor=' + productVendor.value + '&productDescription=' + productDescription.value + '&quantityInStock=' + quantityInStock.value + '&buyPrice=' + buyPrice.value + '&MSRP=' + MSRP.value; http.post(PostURL); }
A business rule to create JSON to post/put in the http request. This method is preferred over method 2 because there is a limit to the length of the URL string which will limit the number of form fields you can pass to the Database Connector.
Code Block language js /*member MSRP, buyPrice, productCode, productDescription, productLine, productName, productScale, productVendor, quantityInStock*/ if (trigger.clicked) { var jp = { productCode: productCode.value, productName: productName.value, productLine: productLine.value, productScale: productScale.value, productVendor: productVendor.value, productDescription: productDescription.value, quantityInStock: quantityInStock.value, buyPrice: buyPrice.value, MSRP: MSRP.value, }; http.post('http://localhost:8082/database/BIRT/productDetails', jp); }
Let’s analyze this rule:
- The first line of the rule is the member directive required by the Live Forms rule validator
- Line 2 is a conditional statement to specify that the rule runs when the Trigger control is clicked
- var jp – defines the JSON payload variable
- The next 9 lines define the JSON payload – specify the form field values that will be written to the columns in the products table.
- The last line specifies the http.post operation to the database connector using the JSON payload. When the user clicks on the Trigger control, the database connector will execute the Insert operation identified by the URL in the productDetails query in the configuration.xml file..
You can also use a combination of data passed by URL parameters and JSON payload. Note that if a form field is specified both via a URL parameter and in the JSON payload, the URL parameter will take precedence. For example you can write a rule like this:
Code Block | ||
---|---|---|
| ||
/*member MSRP, buyPrice, productCode, productDescription, productLine, productName, productScale, productVendor, quantityInStock*/
if (trigger.clicked) {
var jp = {
productCode: productCode.value,
productName: productName.value,
productLine: productLine.value,
productScale: productScale.value,
productVendor: productVendor.value,
productDescription: productDescription.value,
quantityInStock: quantityInStock.value,
buyPrice: buyPrice.value,
MSRP: MSRP.value,
};
http.post('http://localhost:8082/database/BIRT/productDetails?productCode='3', jp);
} |
In this rule the value of “3” specified by the ?productCode=3 URL parameter overrides the value of the JSON object.
Writing rules with http.post and http.put requests eliminates the need to use a stored procedure to update/insert records into your database tables and then call that Stored Procedure from a business rule.
Stored Procedures
The Database Connector supports the use of Stored Procedures to update/insert data into a database table. Existing stored procedures can still be used. However, using the Post/Put to the Database Connector from a Business Rule accomplishes the same thing and is a more straight forward approach than using a stored procedure.
To use a stored procedure, you must:
- Create a stored procedure to update/insert the values into the database table
- Call this stored procedure in the <retrieve> tag of your configuration.xml query
- Use an http.get statement in your business rule to call this query. The stored procedure will execute and update/insert data into your table
Here is an example of a mySql stored procedure.
Code Block |
---|
DELIMITER // CREATE PROCEDURE GetNewOrderNum() BEGIN SELECT max(orderNumber) + 1 as onum FROM Orders; END // DELIMITER ; |
To call this from the mySql command line you would use the command: call GetNewOrderNum(); To call this from the database connector you would add the following to the configuration.xml:
Code Block |
---|
<query name="getOrderNumber">
<retrieve>
<statement> w
call GetNewOrderNum()
</statement>
</retrieve>
</query> |
...
Code Block |
---|
<query name="customers"> <retrieve> <statement> SELECT * FROM customers WHERE emailAddr='%{domain}%' </statement> </retrieve> </query> |