La librería SQL permite conectar a una base de datos y ejecutar sentencias. Es decir, permite incluir dentro de un JSP el acceso a base de datos que normalmente se realiza en la capa de persistencia de una aplicación web tradicional. Evidentemente esta forma de acceso no está recomendada para una aplicación web en un entorno de producción.

Configuración
Para usar la librería es necesario hacer una configuración inicial, aunque se puede omitir y hacerla en tiempo de ejecución utilizando las acciones.

Para realizar el acceso a base de datos se utiliza un DataSource que puede estar disponible a través de JNDI en el servidor, o definido de forma local en la aplicación. Como ejemplo se mostrará el segundo caso, con una conexión a una base de datos Oracle XE.

El DataSource se debe declarar en el fichero web.xml, añadiendo la variable de contexto javax.servlet.jsp.jstl.sql.dataSource con el detalle de la conexión (url, driver, usuario, password):

<context-param>
  <param-name>javax.servlet.jsp.jstl.sql.dataSource</param-name>
  <param-value>
    jdbc:oracle:thin:@localhost:1521:XE,oracle.jdbc.driver.OracleDriver,***,***
  </param-value>
</context-param>

Además se puede definir la variable javax.servlet.jsp.jstl.sql.maxRows que limita el número de filas devueltas por las consultas.

Dependencias
El driver indicado en el DataSource debe estar disponible para la aplicación, por lo que debe añadirse la dependencia correspondiente en el fichero pom.xml de Maven:

<dependency>
  <groupId>com.oracle.jdbc</groupId>
  <artifactId>ojdbc14</artifactId>
  <version>10.2.0.3.0</version>
</dependency>

Este driver no se encuentra distribuido en los repositorios oficiales de Maven, pero es fácil encontrarlo en otros.

Acciones
Todas las acciones permiten especificar el DataSource al que deben atacar. Si no se especifica ninguno se ataca al configurado por defecto.

sql:query: Ejecuta una consulta y deja el resultado en una variable de tipo javax.servlet.jsp.jstl.sql.Result. Opcionalmente se puede especificar el número máximo de filas que puede retornar la consulta y la primera fila que debe retornar, lo que resulta útil para mostrar de forma paginada los registros resultantes.

<sql:query var="empresas">
  SELECT *
    FROM empresa
   ORDER BY nombre
</sql:query>

Una vez obtenida una colección de filas se puede iterar sobre ellas utilizando la acción c:forEach para procesarlas:

<table>
  <c:forEach var="empresa" items="${empresas.rows}">
    <tr>
      <td><c:out value="${empresa.id_Empresa}"/></td>
      <td><c:out value="${empresa.nombre}"/></td>
    </tr>
  </c:forEach>
</table>

sql:update: Ejecuta una sentencia de actualización, o DDL, y deja el número de filas afectadas en la variable indicada.

<sql:update var="modificadas">
  UPDATE empresa
     SET nombre = 'Hard Ink'
   WHERE id_empresa = 5
</sql:update>

sql:transaction: Establece una transacción que se aplica al cuerpo de la acción.

<sql:transaction>
...
</sql:transaction>

sql:setDataSource: Almacena en la variable indicada el DataSource. Si no especifica variable destino se establece en la variable javax.servlet.jsp.jstl.sql.dataSource.

<sql:setDataSource
  url="jdbc:oracle:thin:@localhost:1521:XE"
  driver="oracle.jdbc.driver.OracleDriver"
  user="***"
  password="***"/>

sql:param: Establece el valor de un parámetro de una sentencia.

<sql:query var="empresas">
  SELECT *
    FROM empresa
   WHERE id_empresa = ?
<sql:param>5</sql:param>
</sql:query>

sql:dateParam: Establece el valor de un parámetro de tipo fecha de una sentencia. Permite especificar un parámetro que indica el tipo concreto de fecha a establecer para satisfacer las necesidades concretas de algunos drivers. Admite los valores timestamp, time y date.