The SQL adapter has the tagged value alias.
For more details, see SQL Deployment.
The example accesses the Employee.sqlite database. This SQLite database is installed together with the E2E SQL examples.
<your example path>\Add-ons\SQL\resources\templates\binaries |
In the example below, the <<SQLAdapter>> action node is named read Employee. It will access the database that is associated with the alias Employee in the component diagram.
The input object of the action node is key, which is of complex type EmployeeKey. It is used in the SQL script that is entered in the script section of the action node. The last line of the action script references the Id attribute of the key parameter. The resulting output of the query is returned to the caller in the output object Employee of type ResultEmployee.
Figure: SQL Adapter – Read Example
In the SQL script, all input variables have to be prefixed with IN::
. All columns that are returned from the database should be prefixed with OUT::
. This prefix is optional, but enables consistency checks during the compilation phase.
In the example above , the E2E Model Compiler checks if the columns
ID
, TYPE
,
STREET
,
ZIPCODE
,
CITY
, and
COUNTRY
can be mapped to attributes having the same name in the ResultEmployee class. If the names do not match, the Model Compiler will display an error message.
After receiving the result from the DBMS at runtime, the Bridge checks if the columns can be mapped to the attributes of the output object (upper and lower case is not distinguished). If the E2E xUML Runtime cannot map the result sets to objects, it will throw an error.
In the above example, only one record is expected to be returned from the DBMS because the <<SQLAdapter>> action returns one object only. If the DBMS were to return multiple records, the xUML Runtime would throw an error.
If you want to make the database table partly variable, you can use the tagged values schema and tableQualifier (see SQL Deployment).
S1.TEMPLOYEE
.TQ1TEMPLOYEE
.Both values can be changed on the deployed Bridge service. Also, a combination of both is possible: <schema>.<tableQualifier><table name>.
Some databases handle BLOB columns differently to their other types. Therefore, the E2E Model Compiler must recognize BLOB columns. This is achieved by marking the column name within the IN:: keyword, i.e. IN:<blob column name>
.
If you want to write database records containing columns that are represented by E2E type Blob, you have to use the following in your SQL query
for inserts
IN:<column_name>:<variable_name> |
for example:
INSERT INTO E2ETYPES (E2E_BLOB) VALUES (IN:E2E_BLOB:e2etypes.e2e_blob) |
for updates
<column_name> = IN:<column_name>:<variable_name> |
for example
UPDATE E2ETYPES SET E2E_BLOB = IN:E2E_BLOB:e2etypes.e2e_blob WHERE ID = IN::id |
Note that the usage of |
If you expect a query to return more than one record, your result object must be an array (base type Array). The type of the array elements, in this case the complex type ResultAddress, is defined on the array object by the tagged value arrayElement (stereotype is <<E2EArray>>). The implicit mapping from columns to object attributes works like in the first example.
Figure: SQL Adapter – Query Example
Since Builder 6.0.20.1 / Runtime 2016.9, you can use the SQL Adapter with parameterized statements that get their parameters via a map.
Figure: Dynamic SQL with Parameterized Statement
Within the SQL statement, replace values by :<name of the parameter>. Provide parameter/value pairs in a map called inputBindings. The E2E will identify the map by this name and automatically replace the parameters in the SQL string by the values given by the map.
Do not use numeric parameter identifiers, e.g. :12. However, identifiers like :id2 are allowed. |
You can use parameters with all kinds of SQL statements: with static and dynamic usage of the SQL adapter as well as with all kinds of database access (query, update, delete, ...). Please also respect all restrictions applying to the usage of the static and dynamic SQL Adapter, e.g. to Blob handling.
CLOB values need a special treatment.
They cannot be directly inserted to the map - you have to use the indirect way via a CLOB object:
create aCLOB; set aCLOB.value = inputCLOBValue; set dummy = inputBindings.setMapValue("parameterName", aCLOB); |
Now you can use parameter parameterName in your SQL statement to access the CLOB value.
It is also possible to provide the SQL Adapter with an input string that contains the SQL statement. You can use this to build full dynamic SQL statements.
Note that it can be a security issue, if the input SQL string (or parts of it) comes as an input parameter from outside the service. This would give the caller the possibility to inject malicious code. |
The following figure shows an example of a dynamically generated SQL statement. The adapter expects the input parameter sql, if it does not have a static SQL statement given as value of the sql tag.
Figure: Example of a Dynamic SQL Statement
The SQL string must not contain |
It may be that at development time the name of the table to query is not yet known. In this case you can use dynamic SQL, and build statements that get the table name from e.g. a service setting:
local tableName = setting("Table Name", "temployee"); set sqlStatement = concat("select name, firstname, birthdate from ", tableName, " where id=:id"); |
Security remark: From a security point of view it is important to control the building of the SQL statement.
|
For SELECT
statements, the SQL adapter needs an output record class (or an array of this class, if the statement creates multiple output records) to store the adapter output to. Here the SQL Adapter tries to match the table column names with the attribute names of the output class.
For all types of statements there is an additional output parameter affectedRows. This parameter returns the number of rows affected by the SQL statement. This comes in handy if the modeler must take into account if e.g. updates had some effect or not.
In general, database-specific types are mapped to the E2E Bridge base types like described on Database-Specific Mappings.
If you query a database and want to store the query results in object attributes of base type Boolean, the xUML Runtime tries to map each table column type to the Boolean attribute type. For instance, if a database query returns a string or numeric representation of a Boolean table field like true, false, 1 (for true), or 0 (for false), the xUML Runtime will map these values to the Boolean attribute values true or false accordingly.