a firstworks project
SQL Relay
About Documentation Download Licensing Support News

Programming with SQL Relay using JDBC

The SQL Relay distribution provides a JDBC driver, enabling JDBC applications to access a database through SQL Relay.

Configuring the Driver

The SQL Relay JDBC driver is provided in two jar files: sqlrelay.jar and sqlrelayjdbc.jar. Both must be in the classpath, along with the native SQL Relay client library.

On Linux and Unix, the jar files are usually found under /usr/local/firstworks/java and the native library is usually found in /usr/local/firstworks/lib.

On Windows, the jar files are usually found under C:\Program Files\Firstworks\java and the native library is usually found under C:\Program Files\Firstworks\bin.

The JDBC URL format is:

jdbc:sqlrelay://user:password@host:port:socket

For example:

jdbc:sqlrelay://myuser:mypassword@sqlrserver:9000:/tmp/example.socket

The port defaults to 9000 if not specified. The socket is optional. User and password may also be passed as properties to DriverManager.getConnection() rather than being included in the URL.

Properties

Every URL field can also be supplied as a property passed to DriverManager.getConnection(). Properties always override values parsed out of the URL. The driver recognizes the following property names:

  • Host - Name of the host running SQL Relay.
  • Port - The port that the SQL Relay server is listening on. Defaults to 9000.
  • Socket - The filename of the unix socket that the SQL Relay server is listening on. Optional.
  • User - The username to use when logging into SQL Relay. Also accepted as user.
  • Password - The password to use when logging into SQL Relay. Also accepted as password.
  • Retry Time - If a connection fails, wait this many seconds before trying again. Defaults to 0.
  • Tries - If a connection fails, retry this many times. Defaults to 1.
  • DATE to TimeStamp - If set to yes, true, on, y, t, or 1, columns of type DATE are mapped to java.sql.Timestamp instead of java.sql.Date. Defaults to false.
  • Output Parameter Buffer Size - Buffer size, in bytes, to use for output parameters when the application calls a method that does not have a length parameter. Defaults to 4096.
  • AutoCommit - Controls whether the driver explicitly turns autocommit on or off after connecting. May be set to yes (autocommit on), no (autocommit off), or backend (leave it up to the backend). Defaults to backend.

Sample Session

A good program to test this with is HenPlus, a JDBC command line client. After downloading and installing HenPlus, you can run it as follows:

henplus jdbc:sqlrelay://exampleuser:examplepass@sqlrserver:9000:/tmp/example.socket

Here is a sample henplus session:

[dmuse@fedora bin]$ ./henplus jdbc:sqlrelay://exampleuser:examplepass@sqlrserver:9000:/tmp/example.socket
no readline found (no JavaReadline in java.library.path). Using simple stdin.
using GNU readline (Brian Fox, Chet Ramey), Java wrapper by Bernhard Bablok
henplus config at /home/dmuse/.henplus
----------------------------------------------------------------------------
 HenPlus II 0.9.8 "Yay Labor Day"
 Copyright(C) 1997..2009 Henner Zeller <H.Zeller@acm.org>
 HenPlus is provided AS IS and comes with ABSOLUTELY NO WARRANTY
 This is free software, and you are welcome to redistribute it under the
 conditions of the GNU Public License <http://www.gnu.org/licenses/gpl2.txt>
----------------------------------------------------------------------------
HenPlus II connecting
 url 'jdbc:sqlrelay://exampleuser:examplepass@sqlrserver:9000:/tmp/example.socket'
 driver version 2.1
 oracle - Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
@sqlrelay> create table exampletable (col1 int, col2 varchar2(20));
affected 0 rows (301 msec)
@sqlrelay> insert into exampletable values (1,'hello');
affected 1 rows (71 msec)
@sqlrelay> insert into exampletable values (2,'goodbye');
affected 1 rows (1 msec)
@sqlrelay> select * from exampletable;
------+---------+
 COL1 |  COL2   |
------+---------+
    1 | hello   |
    2 | goodbye |
------+---------+
2 rows in result (first row: 56 msec; total: 57 msec)
@sqlrelay> update exampletable set col2='bye' where col1=2;
affected 1 rows (2 msec)
@sqlrelay> select * from exampletable;
------+-------+
 COL1 | COL2  |
------+-------+
    1 | hello |
    2 | bye   |
------+-------+
2 rows in result (first row: 1 msec; total: 2 msec)
@sqlrelay> delete from exampletable where col1=1;
affected 1 rows (2 msec)
@sqlrelay> select * from exampletable;
------+------+
 COL1 | COL2 |
------+------+
    2 | bye  |
------+------+
1 row in result (first row: 1 msec; total: 1 msec)
@sqlrelay> drop table exampletable;
affected 0 rows (3.637 sec)
@sqlrelay> quit
storing settings..
[dmuse@fedora bin]$

Compiling a JDBC Program

When writing a JDBC application, you need to import java.sql.

import java.sql.*;

You'll also need to include both jar files in your classpath.

On Linux and Unix, the command to compile your .java file will look something like this:

javac -classpath /usr/local/firstworks/java/sqlrelay.jar:/usr/local/firstworks/java/sqlrelayjdbc.jar:. myprogram.java

The command to run your program will look something like this:

java -classpath /usr/local/firstworks/java/sqlrelay.jar:/usr/local/firstworks/java/sqlrelayjdbc.jar:. -Djava.library.path=/usr/local/firstworks/lib myprogram

Establishing a Session

To use JDBC, you get a connection from the DriverManager using a JDBC URL.

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");

                ... execute some queries ...

                con.close();
        }
}

DriverManager.getConnection() connects to the SQL Relay server specified in the URL using the provided credentials.

For the duration of the session, the client occupies one of the database connections, so care should be taken to minimize the length of a session.

Executing Queries

Create a Statement, then call executeQuery() to run a select, or executeUpdate() to run an insert, update, delete, or DDL query. The same Statement may be used for multiple queries.

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");
                Statement stmt=con.createStatement();

                stmt.executeQuery("select * from my_table");

                ... do some stuff that takes a short time ...

                stmt.executeQuery("select * from my_other_table");

                ... process the result set ...

                stmt.close();
                con.close();
        }
}

Commits and Rollbacks

If you need to execute a commit or rollback, you should use the commit() and rollback() methods of the Connection class rather than sending a "commit" or "rollback" query. There are two reasons for this. First, it's much more efficient to call the methods. Second, if you're writing code that can run on transactional or non-transactional databases, some non-transactional databases will throw errors if they receive a "commit" or "rollback" query, but by calling the commit() and rollback() methods you instruct the database connection daemon to call the commit and rollback API methods for that database rather than issuing them as queries. If the API's have no commit or rollback methods, the calls do nothing and the database throws no error.

You can also turn Autocommit on or off using setAutoCommit(). When Autocommit is on, the database performs a commit after each successful DML or DDL query. When Autocommit is off, the database commits when the client instructs it to, or (by default) when a client disconnects. For databases that don't support Autocommit, setAutoCommit() has no effect.

You can also pass an AutoCommit property to DriverManager.getConnection() to control whether the driver explicitly turns autocommit on or off after connecting. May be set to yes (autocommit on), no (autocommit off), or backend (leave it up to the backend). Defaults to backend.

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");

                // turn off autocommit
                con.setAutoCommit(false);

                Statement stmt=con.createStatement();

                stmt.executeUpdate("insert into my_table values (1,2,3)");

                con.commit();

                stmt.executeUpdate("insert into my_table values (4,5,6)");

                con.rollback();

                // turn autocommit back on
                con.setAutoCommit(true);

                stmt.close();
                con.close();
        }
}

Temporary Tables

Some databases support temporary tables. That is, tables which are automatically dropped or truncated when an application closes its connection to the database or when a transaction is committed or rolled back.

For databases which drop or truncate tables when a transaction is committed or rolled back, temporary tables work naturally.

However, for databases which drop or truncate tables when an application closes its connection to the database, there is an issue. Since SQL Relay maintains persistent database connections, when an application disconnects from SQL Relay, the connection between SQL Relay and the database remains, so the database does not know to drop or truncate the table. To remedy this situation, SQL Relay parses each query to see if it created a temporary table, keeps a list of temporary tables and drops (or truncates them) when the application disconnects from SQL Relay. Since each database has slightly different syntax for creating a temporary table, SQL Relay parses each query according to the rules for that database.

In effect, temporary tables should work when an application connects to SQL Relay in the same manner that they would work if the application connected directly to the database.

Catching Errors

If a query fails, JDBC throws a SQLException. You can catch it and call getMessage() to find out why the query failed.

import java.sql.*;

public class myclass {
        public static void main(String[] args) {

                try {
                        Connection con=DriverManager.getConnection(
                                "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");
                        Statement stmt=con.createStatement();

                        stmt.executeQuery(
                                "select * from my_nonexistant_table");

                        stmt.close();
                        con.close();
                } catch (SQLException ex) {
                        System.out.println("Error: "+ex.getMessage());
                }
        }
}

Bind Variables

Programs rarely execute fixed queries. More often than not, some part of the query is dynamically generated. The JDBC API provides means for using bind variables (also known as parameters) in those queries.

For a detailed discussion of binds, see this document.

JDBC provides PreparedStatement for binding values to parameter markers (?) in queries. You call Connection.prepareStatement() to prepare the query, then setString(), setInt(), setDouble(), etc. to bind each parameter, and executeQuery() or executeUpdate() to execute the query.

When passing a floating point number as a bind variable, you can use setDouble() or setFloat(). See this page for a discussion of precision and scale.

Note that JDBC requires question marks (?) as parameter markers, but most databases use other formats natively (eg. :name for Oracle, @name for Sybase/MSSQL, $1 for PostgreSQL). For JDBC bind variables to work against those databases, SQL Relay must be configured to translate them by setting translatebindvariables="yes" in the sqlrelay.conf file for the instance you're using. See the SQL Relay Configuration Reference for more information on this parameter.

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");

                PreparedStatement stmt=con.prepareStatement(
                        "select * from mytable "
                        +"where stringcol=? "
                        +"and integercol>? "
                        +"and floatcol>?");
                stmt.setString(1,"true");
                stmt.setInt(2,10);
                stmt.setDouble(3,1.1);
                ResultSet rs=stmt.executeQuery();

                ... process the result set ...

                rs.close();
                stmt.close();
                con.close();
        }
}

JDBC also supports output bind variables via CallableStatement. This is useful for retrieving data from stored procedure calls. You call registerOutParameter() to define the output parameters, then getInt(), getDouble(), getString(), etc. to retrieve the values after execution.

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");

                CallableStatement stmt=con.prepareCall(
                        "{call addAndConvert(?,?,?,?,?,?,?,?)}");
                stmt.setInt(1,10);
                stmt.setInt(2,20);
                stmt.setDouble(3,1.1);
                stmt.setDouble(4,2.2);
                stmt.setInt(5,30);
                stmt.registerOutParameter(6,Types.INTEGER);
                stmt.registerOutParameter(7,Types.DOUBLE);
                stmt.registerOutParameter(8,Types.VARCHAR);
                stmt.execute();

                int result1=stmt.getInt(6);
                double result2=stmt.getDouble(7);
                String result3=stmt.getString(8);

                ... do something with result1, result2, result3 ...

                stmt.close();
                con.close();
        }
}

ResultSet.getString() returns a NULL value as null. You can call wasNull() to check whether the last value retrieved was NULL.

You can insert data into BLOB and CLOB columns using setBytes() for BLOBs and setString() for CLOBs.

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");

                Statement stmt=con.createStatement();
                stmt.executeUpdate("create table images "
                        +"(image blob, description clob)");
                stmt.close();

                byte[] imagedata;
                long imagelength;

                ... read an image from a file into imagedata and the length of the
                        file into imagelength ...

                String description;
                long desclength;

                ... read a description from a file into description and the length of
                        the file into desclength ...

                PreparedStatement pstmt=con.prepareStatement(
                        "insert into images values (?,?)");
                pstmt.setBytes(1,imagedata);
                pstmt.setString(2,description);
                pstmt.executeUpdate();

                pstmt.close();
                con.close();
        }
}

Likewise, you can retrieve BLOB or CLOB data using getBytes() and getString().

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");
                Statement stmt=con.createStatement();

                ResultSet rs=stmt.executeQuery(
                        "select image, description from images");

                while (rs.next()) {
                        byte[] image=rs.getBytes(1);
                        String desc=rs.getString(2);

                        ... do something with image and desc ...
                }

                rs.close();
                stmt.close();
                con.close();
        }
}

Re-Binding and Re-Executing

Another feature of the prepare/bind/execute paradigm is the ability to prepare a query once, then re-execute the query over and over with different values without re-preparing it. Just call the set methods with new values and call executeQuery() or executeUpdate() again. If your back-end database natively supports this paradigm, you can reap a substantial performance improvement.

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");

                PreparedStatement stmt=con.prepareStatement(
                        "select * from mytable where mycolumn>?");

                stmt.setInt(1,1);
                ResultSet rs=stmt.executeQuery();

                ... process the result set ...

                rs.close();
                stmt.setInt(1,5);
                rs=stmt.executeQuery();

                ... process the result set ...

                rs.close();
                stmt.setInt(1,10);
                rs=stmt.executeQuery();

                ... process the result set ...

                rs.close();
                stmt.close();
                con.close();
        }
}

Accessing Fields in the Result Set

ResultSet.next() and ResultSet.getString() (or getInt(), getDouble(), etc.) are useful for processing result sets. You can get the number of columns using ResultSetMetaData.getColumnCount().

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");
                Statement stmt=con.createStatement();

                ResultSet rs=stmt.executeQuery(
                        "select * from my_table");

                ResultSetMetaData rsmd=rs.getMetaData();
                int cols=rsmd.getColumnCount();

                while (rs.next()) {
                        for (int col=1; col<=cols; col++) {
                                System.out.print(rs.getString(col)+",");
                        }
                        System.out.println();
                }

                rs.close();
                stmt.close();
                con.close();
        }
}

Cursors

Cursors make it possible to execute queries while processing the result set of another query. In JDBC, each Statement acts as a cursor. You can create multiple Statements on the same Connection, allowing you to select rows from one table in one Statement, iterate through its result set, and insert rows into another table using a second Statement, all using a single database connection.

For example:

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");

                Statement stmt1=con.createStatement();
                PreparedStatement stmt2=con.prepareStatement(
                        "insert into my_other_table values (?,?,?)");

                ResultSet rs=stmt1.executeQuery(
                        "select * from my_huge_table");

                while (rs.next()) {
                        stmt2.setString(1,rs.getString(1));
                        stmt2.setString(2,rs.getString(2));
                        stmt2.setString(3,rs.getString(3));
                        stmt2.executeUpdate();
                }

                rs.close();
                stmt2.close();
                stmt1.close();
                con.close();
        }
}

Getting Column Information

For each column, the JDBC API supports getting the name, type name, display size, precision, scale, and nullability via ResultSetMetaData. Additional attributes such as whether the column is auto-incrementing can also be retrieved.

import java.sql.*;

public class myclass {
        public static void main(String[] args) throws Exception {

                Connection con=DriverManager.getConnection(
                        "jdbc:sqlrelay://user:password@sqlrserver:9000:/tmp/example.socket");
                Statement stmt=con.createStatement();

                ResultSet rs=stmt.executeQuery(
                        "select * from my_table");

                ResultSetMetaData rsmd=rs.getMetaData();
                int cols=rsmd.getColumnCount();

                for (int i=1; i<=cols; i++) {
                        System.out.println("Name:           "+rsmd.getColumnName(i));
                        System.out.println("Type:           "+rsmd.getColumnTypeName(i));
                        System.out.println("Display Size:   "+rsmd.getColumnDisplaySize(i));
                        System.out.println("Precision:      "+rsmd.getPrecision(i));
                        System.out.println("Scale:          "+rsmd.getScale(i));
                        System.out.println("Nullable:       "+rsmd.isNullable(i));
                        System.out.println("Auto Increment: "+rsmd.isAutoIncrement(i));
                        System.out.println();
                }

                rs.close();
                stmt.close();
                con.close();
        }
}

Stored Procedures

Many databases support stored procedures. Stored procedures are sets of queries and procedural code that are executed inside of the database itself. For example, a stored procedure may select rows from one table, iterate through the result set and, based on the values in each row, insert, update or delete rows in other tables. A client program could do this as well, but a stored procedure is generally more efficient because queries and result sets don't have to be sent back and forth between the client and database. Also, stored procedures are generally stored in the database in a compiled state, while queries may have to be re-parsed and re-compiled each time they are sent.

While many databases support stored procedures. The syntax for creating and executing stored procedures varies greatly between databases.

Stored procedures typically take input paramters from client programs through input bind variables and return values back to client programs either through bind variables or result sets. Stored procedures can be broken down into several categories, based on the values that they return. Some stored procedures don't return any values, some return a single value, some return multiple values and some return entire result sets.

No Values

Some stored procedures don't return any values. Below are examples, illustrating how to create, execute and drop this kind of stored procedure for each database that SQL Relay supports.

Oracle

To create the stored procedure, run a query like the following.

create procedure exampleproc(in1 in number, in2 in number, in3 in varchar2) is
begin
        insert into mytable values (in1,in2,in3);
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("begin exampleproc(?,?,?); end;");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.executeUpdate();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Sybase and Microsoft SQL Server

To create the stored procedure, run a query like the following.

create procedure exampleproc @in1 int, @in2 float, @in3 varchar(20) as
        insert into mytable values (@in1,@in2,@in3)

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("{call exampleproc(?,?,?)}");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.execute();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Firebird

To create the stored procedure, run a query like the following.

create procedure exampleproc(in1 integer, in2 float, in3 varchar(20)) as
begin
        insert into mytable values (in1,in2,in3);
        suspend;
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("execute procedure exampleproc ?, ?, ?");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.executeUpdate();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

DB2

To create the stored procedure, run a query like the following.

create procedure exampleproc(in in1 int, in in2 double, in in3 varchar(20)) language sql
begin
        insert into mytable values (in1,in2,in3);
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("{call exampleproc(?,?,?)}");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.execute();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Postgresql

To create the stored procedure, run a query like the following.

create function examplefunc(int,float,varchar(20)) returns void as '
begin
        insert into mytable values ($1,$2,$3);
        return;
end;' language plpgsql

To execute the stored procedure from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("select examplefunc(?,?,?)");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.executeQuery();
stmt.close();

To drop the stored procedure, run a query like the following.

drop function examplefunc(int,float,varchar(20))

MySQL/MariaDB

To create the stored procedure, run a query like the following.

create procedure exampleproc(in in1 int, in in2 float, in in3 varchar(20))
begin
        insert into mytable values (in1,in2,in3);
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("{call exampleproc(?,?,?)}");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.execute();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Single Values

Some stored procedures return single values. Below are examples, illustrating how to create, execute and drop this kind of stored procedure for each database that SQL Relay supports.

Oracle

In Oracle, stored procedures can return values through output parameters or as return values of the procedure itself.

Here is an example where the procedure itself returns a value. Note that Oracle calls these functions.

To create the stored procedure, run a query like the following.

create function exampleproc(in1 in number, in2 in number, in3 in varchar2) returns number is
begin
        return in1;
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("select exampleproc(?,?,?) from dual");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
ResultSet rs=stmt.executeQuery();
rs.next();
String result=rs.getString(1);
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Here is an example where the value is returned through an output parameter.

To create the stored procedure, run a query like the following.

create procedure exampleproc(in1 in number, in2 in number, in3 in varchar2, out1 out number) as
begin
        out1:=in1;
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("begin exampleproc(?,?,?,?); end;");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.registerOutParameter(4,Types.INTEGER);
stmt.execute();
int result=stmt.getInt(4);
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Sybase and Microsoft SQL Server

In Sybase and Microsoft SQL Server, stored procedures return values through output parameters rather than as return values of the procedure itself.

To create the stored procedure, run a query like the following.

create procedure exampleproc @in1 int, @in2 float, @in3 varchar(20), @out1 int output as
        select @out1=convert(varchar(20),@in1)

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("{call exampleproc(?,?,?,?)}");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.registerOutParameter(4,Types.INTEGER);
stmt.execute();
int result=stmt.getInt(4);
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Firebird

To create the stored procedure, run a query like the following.

create procedure exampleproc(in1 integer, in2 float, in3 varchar(20)) returns (out1 integer) as
begin
        out1=in1;
        suspend;
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("select * from exampleproc(?, ?, ?)");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
ResultSet rs=stmt.executeQuery();
rs.next();
String result=rs.getString(1);
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

DB2

In DB2, stored procedures return values through output parameters rather than as return values of the procedure itself.

To create the stored procedure, run a query like the following.

create procedure exampleproc(in in1 int, in in2 double, in in3 varchar(20), out out1 int) language sql
begin
        set out1 = in1;
end

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("{call exampleproc(?,?,?,?)}");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.registerOutParameter(4,Types.INTEGER);
stmt.execute();
int result=stmt.getInt(4);
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Postgresql

To create the stored procedure, run a query like the following.

create function examplefunc(int,float,char(20)) returns int as '
declare
        in1 int;
        in2 float;
        in3 char(20);
begin
        in1:=$1;
        return;
end;
' language plpgsql

To execute the stored procedure from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("select * from examplefunc(?,?,?)");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
ResultSet rs=stmt.executeQuery();
rs.next();
String result=rs.getString(1);
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop function examplefunc(int,float,char(20))

MySQL/MariaDB

A single value can be returned from a MySQL/MariaDB function.

To create the function, run a query like the following.

create function examplefunc(in in1 int, in in2 float, in in3 varchar(20)) returns int return in1;

To execute the function from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("select examplefunc(?,?,?)");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
ResultSet rs=stmt.executeQuery();
rs.next();
String result=rs.getString(1);
rs.close();
stmt.close();

To drop the function, run a query like the following.

drop procedure exampleproc

A single value can be returned in the result set of a MySQL/MariaDB procedure.

To create the procedure, run a query like the following.

create procedure exampleproc() begin select 1; end;

To execute the procedure from an SQL Relay program, use code like the following.

Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("{call exampleproc}");
rs.next();
String result=rs.getString(1);
rs.close();
stmt.close();

To drop the procedure, run a query like the following.

drop procedure exampleproc

A single value can be returned using the output variable of a MySQL/MariaDB procedure.

To create the procedure, run a query like the following.

create procedure exampleproc(out out1 int) begin select 1 into out1; end;

To execute the procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("{call exampleproc(?)}");
stmt.registerOutParameter(1,Types.INTEGER);
stmt.execute();
int result=stmt.getInt(1);
stmt.close();

To drop the procedure, run a query like the following.

drop procedure exampleproc

Multiple Values

Some stored procedures return multiple values. Below are examples, illustrating how to create, execute and drop this kind of stored procedure for each database that SQL Relay supports.

Oracle

In Oracle, stored procedures can return values through output parameters or as return values of the procedure itself. If a procedure needs to return multiple values, it can return one of them as the return value of the procedure itself, but the rest must be returned through output parameters.

To create the stored procedure, run a query like the following.

create procedure exampleproc(in1 in number, in2 in number, in3 in varchar2, out1 out number, out2 out number, out3 out varchar2) is
begin
        out1:=in1;
        out2:=in2;
        out3:=in3;
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("begin exampleproc(?,?,?,?,?,?); end;");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.registerOutParameter(4,Types.INTEGER);
stmt.registerOutParameter(5,Types.DOUBLE);
stmt.registerOutParameter(6,Types.VARCHAR);
stmt.execute();
int out1=stmt.getInt(4);
double out2=stmt.getDouble(5);
String out3=stmt.getString(6);
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Sybase and Microsoft SQL Server

To create the stored procedure, run a query like the following.

create procedure exampleproc @in1 int, @in2 float, @in3 varchar(20), @out1 int output, @out2 int output, @out3 int output as
        select @out1=convert(varchar(20),@in1),
                @out2=convert(varchar(20),@in2),
                @out2=convert(varchar(20),@in2)

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("{call exampleproc(?,?,?,?,?,?)}");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.registerOutParameter(4,Types.INTEGER);
stmt.registerOutParameter(5,Types.DOUBLE);
stmt.registerOutParameter(6,Types.VARCHAR);
stmt.execute();
int out1=stmt.getInt(4);
double out2=stmt.getDouble(5);
String out3=stmt.getString(6);
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Firebird

To create the stored procedure, run a query like the following.

create procedure exampleproc(in1 integer, in2 float, in3 varchar(20)) returns (out1 integer, out2 float, out3 varchar(20)) as
begin
        out1=in1;
        out2=in2;
        out3=in3;
        suspend;
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("select * from exampleproc(?, ?, ?)");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
ResultSet rs=stmt.executeQuery();
rs.next();
String out1=rs.getString(1);
String out2=rs.getString(2);
String out3=rs.getString(3);
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

DB2

To create the stored procedure, run a query like the following.

create procedure exampleproc(in in1 int, in in2 double, in in3 varchar(20), out out1 int, out out2 double, out out3 varchar(20)) language sql
begin
        set out1 = in1;
        set out2 = in2;
        set out3 = in3;
end

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("{call exampleproc(?,?,?,?,?,?)}");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
stmt.registerOutParameter(4,Types.INTEGER);
stmt.registerOutParameter(5,Types.DOUBLE);
stmt.registerOutParameter(6,Types.VARCHAR);
stmt.execute();
int out1=stmt.getInt(4);
double out2=stmt.getDouble(5);
String out3=stmt.getString(6);
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Postgresql

To create the stored procedure, run a query like the following.

create function examplefunc(int,float,char(20)) returns record as '
declare
        output record;
begin
        select $1,$2,$3 into output;
        return output;
end;
' language plpgsql

To execute the stored procedure from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("select * from examplefunc(?,?,?) as (col1 int, col2 float, col3 char(20))");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
ResultSet rs=stmt.executeQuery();
rs.next();
String out1=rs.getString(1);
String out2=rs.getString(2);
String out3=rs.getString(3);
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop function examplefunc(int,float,char(20))

MySQL/MariaDB

Here's how you can get multiple values from the result set of a MySQL/MariaDB procedure.

To create the stored procedure, run a query like the following.

create procedure exampleproc(in in1 int, in in2 float, in in3 varchar(20)) begin select in1, in2, in3; end;

To execute the stored procedure from an SQL Relay program, use code like the following.

PreparedStatement stmt=con.prepareStatement("{call exampleproc(?,?,?)}");
stmt.setInt(1,1);
stmt.setDouble(2,1.1);
stmt.setString(3,"hello");
ResultSet rs=stmt.executeQuery();
rs.next();
String out1=rs.getString(1);
String out2=rs.getString(2);
String out3=rs.getString(3);
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Here's how you can get multiple values from the output variables of a MySQL/MariaDB procedure.

To create the stored procedure, run a query like the following.

create procedure exampleproc(out out1 int, out out2 float, out out3 varchar(20)) begin select 1,1.1,'hello' into out1, out2, out3; end;

To execute the stored procedure from an SQL Relay program, use code like the following.

CallableStatement stmt=con.prepareCall("{call exampleproc(?,?,?)}");
stmt.registerOutParameter(1,Types.INTEGER);
stmt.registerOutParameter(2,Types.DOUBLE);
stmt.registerOutParameter(3,Types.VARCHAR);
stmt.execute();
int out1=stmt.getInt(1);
double out2=stmt.getDouble(2);
String out3=stmt.getString(3);
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Result Sets

Some stored procedures return entire result sets. Below are examples, illustrating how to create, execute and drop this kind of stored procedure for each database that SQL Relay supports.

Oracle

To create the stored procedure, run a query like the following.

create or replace package types as
        type cursorType is ref cursor;
end;

create function exampleproc return types.cursortype is
        l_cursor    types.cursorType;
begin
        open l_cursor for select * from mytable;
        return l_cursor;
end;

To execute the stored procedure from an SQL Relay program, use code like the following.

Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("begin open :curs for select * from mytable; end;");
while (rs.next()) {
        String col1=rs.getString(1);
        String col2=rs.getString(2);
        String col3=rs.getString(3);
        ... process col1, col2, col3 ...
}
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop function exampleproc
drop package types

Sybase and Microsoft SQL Server

To create the stored procedure, run a query like the following.

create procedure exampleproc as select * from exampletable

To execute the stored procedure from an SQL Relay program, use code like the following.

Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("{call exampleproc}");
while (rs.next()) {
        String col1=rs.getString(1);
        String col2=rs.getString(2);
        String col3=rs.getString(3);
        ... process col1, col2, col3 ...
}
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Firebird

Stored procedures in Firebird can return a result set if a select query in the procedure selects values into the output parameters and then issues a suspend command, however SQL Relay doesn't currently support stored procedures that return result sets.

DB2

Stored procedures in DB2 can return a result set if the procedure is declared to return one, however SQL Relay doesn't currently support stored procedures that return result sets.

Postgresql

To create the stored procedure, run a query like the following.

create function examplefunc() returns setof record as '
        declare output record;
begin
        for output in select * from mytable loop
                return next output;
        end loop;
        return;
end;
' language plpgsql

To execute the stored procedure from an SQL Relay program, use code like the following.

Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("select * from examplefunc() as (col1 int, col2 float, col3 char(40))");
while (rs.next()) {
        String col1=rs.getString(1);
        String col2=rs.getString(2);
        String col3=rs.getString(3);
        ... process col1, col2, col3 ...
}
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop function examplefunc

MySQL/MariaDB

The result sets of all select statements called within MySQL/MariaDB stored procedures (that aren't selected into variables) are returned from the procedure call. Though MySQL/MariaDB stored procedures can return multiple result sets, currently SQL Relay can only fetch the first result set.

To create the stored procedure which returns a result set, run a query like the following.

create procedure exampleproc() begin select * from mytable; end;

To execute the stored procedure from an SQL Relay program, use code like the following.

Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("{call exampleproc}");
while (rs.next()) {
        String col1=rs.getString(1);
        String col2=rs.getString(2);
        String col3=rs.getString(3);
        ... process col1, col2, col3 ...
}
rs.close();
stmt.close();

To drop the stored procedure, run a query like the following.

drop procedure exampleproc

Copyright 2024 - David Muse - Contact