title: SQLJ
text: # SQLJ
  
  SQLJ es un estándar ISO (ISO/IEC 9075-10) para embeber sentencias SQL en programas de Lenguaje de programación Java.
  Al contrario que JDBC, SQLJ no es una API sino una extensión del lenguaje. Así, los programas SQLJ deben ejecutarse a través de un preprocesador (el traductor SQLJ) antes de que puedan ser compilados.
  SQLJ tiene varias ventajas sobre JDBC:
  * Los programas SQLJ son más fáciles de escribir y de mantener. Además tienden a ser más cortos que los programas JDBC equivalentes.
  * Es más eficiente que JDBC dado que las sentencias SQL son analizadas y los caminos de acceso son optimizados en tiempo de compilación en lugar de en tiempo de ejecución.
  * Suministra mejor control de autorización: La Autorización puede ser concedida a los programas en lugar de a los usuarios.
  * Los problemas de rendimiento potenciales, tales como las consultas ineficientes debido a un mal camino de acceso, pueden ser identificados en tiempo de desarrollo.
  Hay varias desventajas:
  * SQLJ requiere un paso de preprocesamiento.
  * Muchos IDEs no proporcionan soporte SQLJ.
  * No hay soporte de SQLJ para la mayoría de frameworks de persistencia comunes, tales como Hibernate.
  
  # SQLJ
  ## Ejemplos
  
  Los siguientes ejemplos comparan la sintaxis de SQLJ con la utilización de JDBC.
  | JDBC | SQLJ |
  | Consulta de varias filas ||
  | PreparedStatement stmt = conn.prepareStatement( "SELECT LASTNAME" + ", FIRSTNME" + ", SALARY" + " FROM DSN8710.EMP" + " WHERE SALARY BETWEEN ? AND ?"); stmt.setBigDecimal(1, min); stmt.setBigDecimal(2, max); ResultSet rs = stmt.executeQuery; while (rs.next) { lastname = rs.getString(1); firstname = rs.getString(2); salary = rs.getBigDecimal(3); // Imprimir fila... } rs.close; stmt.close; | #sql private static iterator EmployeeIterator(String, String, BigDecimal); ... EmployeeIterator iter; #sql [ctx] iter = { SELECT LASTNAME , FIRSTNME , SALARY FROM DSN8710.EMP WHERE SALARY BETWEEN:min AND:max }; while (true) { #sql { FETCH:iter INTO:lastname,:firstname,:salary }; if (iter.endFetch) break; // Imprimir fila... } iter.close; |
  | Consulta de una fila ||
  | PreparedStatement stmt = conn.prepareStatement( "SELECT MAX(SALARY), AVG(SALARY)" + " FROM DSN8710.EMP"); rs = statement.executeQuery; if (!rs.next) { // Error -- no se encontraron filas } maxSalary = rs.getBigDecimal(1); avgSalary = rs.getBigDecimal(2); if (rs.next) { // Error -- más de una fila encontrada } rs.close; stmt.close; | #sql [ctx] { SELECT MAX(SALARY), AVG(SALARY) INTO:maxSalary,:avgSalary FROM DSN8710.EMP }; |
  | INSERT ||
  | stmt = conn.prepareStatement( "INSERT INTO DSN8710.EMP " + "(EMPNO, FIRSTNME, MIDINIT, LASTNAME, HIREDATE, SALARY) " + "VALUES (?, ?, ?, ?, CURRENT DATE, ?)"); stmt.setString(1, empno); stmt.setString(2, firstname); stmt.setString(3, midinit); stmt.setString(4, lastname); stmt.setBigDecimal(5, salary); stmt.executeUpdate; stmt.close; | #sql [ctx] { INSERT INTO DSN8710.EMP (EMPNO, FIRSTNME, MIDINIT, LASTNAME, HIREDATE, SALARY) VALUES (:empno,:firstname,:midinit,:lastname, CURRENT DATE,:salary) }; |