Introduction to Using the Database Package - Maple Programming Help

Home : Support : Online Help : Connectivity : Database Package : Database/usage

Introduction to Using the Database Package

Package Structure

 • Database uses an object oriented design.  As such, some commands in the Database package return modules. These modules export commands that comprise the majority of the Database package functionality.
 • Each module that is returned is an instance of a class.  A class defines the commands that are exported by the module.  A module of a class must export all the commands defined by the class.

Help Page Conventions

 • The Database help pages use the following conventions.
 - A package export is referred to using table notation, for example, Database[LoadDriver].
 - An exported command of a returned module uses :- notation.  The left-hand side of the :- is written using italic font, for example, Driver:-OpenConnection. The name on the left-hand side of the :- can be viewed as the class name, thus defining the exported commands of the module, or as a user-defined name for the returned module, thus providing an example calling sequence.

Structured Query Language

 • Structured Query Language (SQL) is a standard language that is used to manipulate data in databases. Without any SQL knowledge, you can use the Query Builder Maplet application to construct SQL queries. To query and update the database, use commands to execute SQL statements.
 Although you do not need any SQL knowledge to use the Database package, a basic understanding of SQL helps you build queries. SQL tutorials are available on the Internet. Also, many books on SQL are available.

Using the Database Package

Database Assistants

 • The Database package provides two Assistants.  The Connection Builder facilitates the creation of Connection objects.  All the information needed to open a connection can be entered into the Assistant.  It also provides methods to load and save this information to a file.  The saved connections can then be reloaded with the Connection Builder or through the LoadConnection command.  The Connection Builder Assistant can be opened using either of the following commands:
 > Database():
 > Database:-ConnectionBuilder():
 • The Query Builder Assistant is used to visually construct queries.  This allows data from a database to be accessed without using SQL.  The Query Builder has two views, the Simple view and the Advanced view.  The Simple view can be used for basic queries and is a good starting place for users with little experience with database queries.  The Advanced view can construct more complex queries using aliases, joins, column expressions, and more.  The Query Builder Assistant can be started by using the following command:
 > Database:-QueryBuilder():

Database Commands

 • To connect to a database, you must load a Java Database Connectivity (JDBC) driver. For information on installing a JDBC driver, see JDBC.  The JDBC driver is loaded using LoadDriver.  This returns a Driver module which represents the loaded driver.
 A Driver module exports the command OpenConnection, which can be used to create a connection to the database.  A login name, a password, and the location of the database are all required to open a connection. OpenConnection returns a Connection module. After establishing a connection, you can save it by using the Save command, so that you can easily reopen it by using the LoadConnection command.
 > driver, connection := Database():
 • Once the connection has been opened, the database can be accessed. Simple queries and updates can be executed using ExecuteQuery and ExecuteUpdate.  However, for more complex queries, use a Statement.
 You can also use the Query Builder Maplet application to construct SQL queries.
 • There are two kinds of statements.  The basic Statement allows a string of SQL to be passed to the database.  The string can be a query, an update or a combination of the two. These statements can be created by calling CreateStatement.  The other kind of statement is a Prepared Statement.  A Prepared Statement acts like a function call and allows data to be inserted into the SQL string on execution.  For example, a Prepared Statement representing an insert can be used multiple times with different arguments to insert multiple data items into the database.  A Prepared Statement module can be created using CreatePreparedStatement.
 Statement and Prepared Statement modules export a command, Execute, which sends a SQL statement to the database.  For a Statement, Execute takes the SQL string to be executed.  A Prepared Statement takes the values to be inserted into its statement. A statement may generate multiple results.  A result is either an integer, representing the number of updates performed, or a Result module, representing an SQL table. The first result is returned by the call to Execute.  Other results can be obtained by calling NextResult.
 A Result module represents an SQL table containing the rows selected by a query.  To access these results, the Result module maintains a cursor which indicates a row in the table.  The cursor can be moved using various commands, including Next, Previous and GotoRow. Data from the current row is accessed using the GetData command.
 Some SQL data types are not easily represented in Maple, or they may be very large and so it is more convenient to access them in smaller pieces. To represent these cases, a DataInterface module is used.  The current version of the Database package does not support many of the complex SQL data types (see compatibility). Therefore, currently the DataInterface module is used only for streaming character or binary types.
 • The following commands may return a module: LoadDriver, OpenConnection, ExecuteQuery, CreateStatement, CreatePreparedStatement, Execute, NextResult and GetData
 • While Database attempts to be as platform and database independent as possible, there are still some compatibility issues.  The issues page documents some known issues and workarounds for particular databases.

Storing Maple Objects

 • There is currently no direct support in Database for storing arbitrary Maple objects in a database.  However, Maple objects can be stored by using sprintf to convert them to a string in ".m" format.  These strings can then be stored in a database.  To recover the Maple object, retrieve the string from the database and the convert it back to Maple using sscanf.

Examples

First create the driver module.  This loads the JDBC driver and prepares to connect to the database.  This returns a module, which you assign to the variable driver.

 > $\mathrm{driver}≔\mathrm{Database}\left[\mathrm{LoadDriver}\right]\left('\mathrm{driver}'="com.database.Driver",'\mathrm{classpath}'="/path/to/jar/jdbc3.jar"\right)$
 ${\mathrm{driver}}{≔}{\mathbf{module}}\left({}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{option}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{unload}}{=}{\mathrm{Close}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{local}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{handle}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{export}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{OpenConnection}}{,}{\mathrm{Close}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end module}}$ (1)

Using the module, driver, you can open a connection to the database.  This returns another module that is assigned to connection.

 > $\mathrm{connection}≔\mathrm{driver}:-\mathrm{OpenConnection}\left("jdbc:database://localhost/Data","username","password"\right)$
 ${\mathrm{connection}}{≔}{\mathbf{module}}\left({}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{option}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{unload}}{=}{\mathrm{Close}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{local}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{handle}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{export}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{ExecuteQuery}}{,}{\mathrm{ExecuteUpdate}}{,}{\mathrm{CreateStatement}}{,}{\mathrm{CreateCallableStatement}}{,}{\mathrm{CreatePreparedStatement}}{,}{\mathrm{Commit}}{,}{\mathrm{Rollback}}{,}{\mathrm{Close}}{,}{\mathrm{SetOptions}}{,}{\mathrm{GetOptions}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end module}}$ (2)

You can use the ExecuteQuery export of connection to begin accessing data from the database.  Since the SQL statement is a query,  you will receive a Result module.

 > $\mathrm{result}≔\mathrm{connection}:-\mathrm{ExecuteQuery}\left("SELECT id,name FROM dataTable"\right)$
 ${\mathrm{result}}{≔}{\mathbf{module}}\left({}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{option}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{unload}}{=}{\mathrm{Close}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{local}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{handle}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{export}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{Next}}{,}{\mathrm{Previous}}{,}{\mathrm{Last}}{,}{\mathrm{First}}{,}{\mathrm{GetRowNumber}}{,}{\mathrm{GotoRow}}{,}{\mathrm{GetRowCount}}{,}{\mathrm{InsertRow}}{,}{\mathrm{DeleteRow}}{,}{\mathrm{UpdateRow}}{,}{\mathrm{GetData}}{,}{\mathrm{UpdateData}}{,}{\mathrm{GetType}}{,}{\mathrm{GetName}}{,}{\mathrm{GetColumnCount}}{,}{\mathrm{SetOptions}}{,}{\mathrm{GetOptions}}{,}{\mathrm{Close}}{,}{\mathrm{ToMaple}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end module}}$ (3)

Step through the table, accessing the columns from each row.

 > $\mathbf{while}\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}\mathrm{result}:-\mathrm{Next}\left(\right)\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}\mathbf{do}\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{result}:-\mathrm{GetData}\left(1\right);\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\phantom{\rule[-0.0ex]{2.0em}{0.0ex}}\mathrm{result}:-\mathrm{GetData}\left(2\right)\phantom{\rule[-0.0ex]{0.0em}{0.0ex}}\mathbf{end}\phantom{\rule[-0.0ex]{0.3em}{0.0ex}}\mathbf{do}$
 ${1}$
 ${"John"}$
 ${2}$
 ${"Jerry"}$
 ${3}$
 ${"Jane"}$
 ${4}$
 ${"Jennifer"}$ (4)

Using a Prepared Statement, you can select individual rows based on the value in their id column without having to enter nearly identical SQL statements multiple times.

 > $\mathrm{pstat}≔\mathrm{connection}:-\mathrm{CreatePreparedStatement}\left("SELECT id,name FROM dataTable WHERE id = ?"\right)$
 ${\mathrm{pstat}}{≔}{\mathbf{module}}\left({}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{option}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{unload}}{=}{\mathrm{Close}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{local}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{handle}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{export}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{Execute}}{,}{\mathrm{NextResult}}{,}{\mathrm{Close}}{,}{\mathrm{SetOptions}}{,}{\mathrm{GetOptions}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end module}}$ (5)

The value given to Execute is inserted into the SQL statement so this selects the row with id = 1.

 > $\mathrm{result}≔\mathrm{pstat}:-\mathrm{Execute}\left(1\right):$$\mathrm{result}:-\mathrm{Next}\left(\right)$
 ${\mathrm{true}}$ (6)
 > $\mathrm{result}:-\mathrm{GetData}\left(1\right)$
 ${1}$ (7)
 > $\mathrm{result}:-\mathrm{GetData}\left(2\right)$
 ${"John"}$ (8)

The Prepared Statement can be reused with different data.

 > $\mathrm{result}≔\mathrm{pstat}:-\mathrm{Execute}\left(2\right):$$\mathrm{result}:-\mathrm{Next}\left(\right)$
 ${\mathrm{true}}$ (9)
 > $\mathrm{result}:-\mathrm{GetData}\left(1\right)$
 ${2}$ (10)
 > $\mathrm{result}:-\mathrm{GetData}\left(2\right)$
 ${"Jerry"}$ (11)