Executing Stored Procedures and SQL Queries
Sophisticated control
When transferring data from or to a database table, you may need more
sophisticated control over the data link than offered by the standard
DatabaseTable
interface. AIMMS offers you this additional control by
letting you have access to stored procedures as well as letting you
execute SQL statements directly. The following two paragraphs provide
some examples where such control may be useful.
Useful for data processing
Your application may require its data in a somewhat different form than is directly available in the database. In this case you may have to perform some pre-processing of the data in the database. Similarly, you may want to perform post-processing in the database after writing data to it. In such circumstances you may call a stored procedure to perform these tasks for you.
Useful for dynamic access
In some cases, the required data for your application may need to be the
result of a parameterized query of the database, i.e. a database table
whose contents is dependent on one or more parameters which are only
known during runtime. Such dynamic tables are usually obtained as the
result set of a stored procedure or of a parameterized query. In this
case AIMMS will allow you to use a stored procedure call or a
dynamically composed SQL query inside the READ
statement as if it
were a database table. Please note that it’s currently not possible to
read a result set from an Oracle stored procedure, since Oracle uses a
non-standard mechanism for that (involving so-called ref cursors).
The DatabaseProcedure
declaration
Every stored procedure or SQL query that you want to call from within
AIMMS must be declared as a DatabaseProcedure
within your
application. The attributes of a DatabaseProcedure
are listed in
this table.
Attribute |
Value type |
See also page |
---|---|---|
|
string |
|
|
argument-list |
|
|
string-expression |
|
|
string-expression |
|
|
string-expression |
|
|
|
|
|
mapping-list |
|
|
comment string |
|
|
convention |
The Convention attribute, Globally Overriding Units Through Conventions |
SQL query or stored procedure
A DatabaseProcedure
in AIMMS can represent either a (dynamically
created) SQL query or a call to a stored procedure. AIMMS makes the
distinction on the basis of the StoredProcedure
and SQLQuery
attributes. If the StoredProcedure
attribute is nonempty, AIMMS
assumes that the DatabaseProcedure
represents a stored procedure and
expects the SQLQuery
attribute to be empty, and vice versa.
The StoredProcedure
attribute
With the StoredProcedure
attribute you can specify the name of the
stored procedure within the ODBC data source that you want to be called.
The StoredProcedure
wizard will let you select any stored procedure
name available within the specified ODBC data source. If the stored
procedure that you want to call is not owned by yourself, or if there
are name conflicts, you should specify the owner with the Owner
attribute.
The SQLQuery
attribute
You can use the SQLQuery
attribute to specify the SQL query that you
want to be executed when the DatabaseProcedure
is called. The value
of this attribute can be any string expression, allowing you to generate
a dynamic SQL query using the arguments of the DatabaseProcedure
.
The Arguments
attribute
With the Arguments
attribute you can indicate the list of scalar
arguments of the database procedure. The specified arguments must have a
matching declaration in a declaration section local to the
DatabaseProcedure
. If the DatabaseProcedure
represents a stored
procedure, the argument list is interpreted as the argument list of the
stored procedure. When you use the StoredProcedure
wizard, AIMMS
will automatically enter the argument list, including their AIMMS
prototype, for you. For a DatabaseProcedure
representing an SQL
query, you can use the arguments in composing the SQL query string.
Input-output type
For SQL queries all arguments must be Input
arguments, as the query
cannot modify them. For stored procedures, the StoredProcedure
wizard will by default set the input-output type of each argument equal
to its SQL input-output type. However, if you want to discard the result
of any output argument, you can change its type to Input
.
The Property
attribute
With the Property
attribute of a DatabaseProcedure
you can
indicate the intended use of the procedure.
When you do not specify the property
UseResultSet
, AIMMS lets you call theDatabaseProcedure
as if it were an AIMMS procedure.When you do specify the property
UseResultSet
, AIMMS lets you use theDatabaseProcedure
as a parameterized table in theREAD
statement. In that case, you can also provide aMapping
attribute to specify the mapping from column names in the result set onto the corresponding AIMMS identifiers.
Stored procedure examples
The following declarations will make two stored procedures contained in
the data source Topological Data
available in your AIMMS
application. The local declarations of all arguments are omitted for the
sake of brevity. They are all assumed to be Input
arguments.
DatabaseProcedure StoreSingleTransport {
DataSource : "Topological Data";
StoredProcedure : "SP_STORE_SINGLE_TRANSPORT";
Arguments : (from, to, transport);
}
DatabaseProcedure SelectTransportNetwork {
DataSource : "Topological Data";
StoredProcedure : "SP_DISTANCE";
Arguments : MaxDistance;
Property : UseResultSet;
Mapping : {
"from" --> i,
"to" --> j,
"dist" --> Distance(i,j),
("from","to") --> Routes
}
}
The procedure StoreSingleTransport
can be used like any other AIMMS
procedure, as in the following statement.
StoreSingleTransport( 'Amsterdam', 'Rotterdam',
Transport('Amsterdam', 'Rotterdam') );
The second procedure SelectTransportNetwork
can be used in a
READ
statement as if it were a database table, as illustrated below.
read from table SelectTransportNetwork( UserSelectedDistance );
SQL query example
The following example illustrates the declaration of a
DatabaseProcedure
representing a direct SQL query. Its aim is to
delete those records in the specified table for which the column
VersionCol
equals the specified version. Both arguments must be
declared as local Input
string parameters.
DatabaseProcedure DeleteTableVersion {
DataSource : "Topological Data";
Arguments : (DeleteTable, DeleteVersion);
SQLQuery : {
FormatString( "DELETE FROM %s WHERE VersionCol = '%s'",
DeleteTable, DeleteVersion )
}
}
Executing SQL statements directly
In addition to executing SQL queries through DatabaseProcedure
,
AIMMS also allows you to execute SQL statements directly within a data
source. The interface for this mechanism is simple, and forms a
convenient alternative for a DatabaseProcedure
when you want to
execute a single SQL statement only once.
The procedure DirectSQL
You can send SQL statements to a data source by calling the procedure
DirectSQL
with the following prototype:
DirectSQL
(data-source, SQL-string)
Both arguments of the procedure should be string expressions. Note that in case the SQL statement also produces a result set, then this set is ignored by AIMMS.
Example
The following call to DirectSQL
drops a table called
"Temporary_Table
from the data source Topological Data"
.
DirectSQL( "Topological Data",
"DROP TABLE Temporary_Table" );
Use FormatString
The procedure DirectSQL
does not offer direct capabilities for
parameterizing the SQL string with AIMMS data. Instead, you can use the
function FormatString
to construct symbolic SQL statements with
terms based on AIMMS identifiers.