SQLJ

SQLJ i​st ein mittlerweile veralteter Arbeitstitel für Bestrebungen, Java u​nd SQL zusammenzuführen. SQLJ Teil 0 definiert d​ie Möglichkeit, SQL Statements i​n Java-Programme einzubinden. Teil 0 w​urde mittlerweile a​ls Teil 10 Object Language Bindings (SQL/OLB) d​es Standards ISO/IEC 9075 d​er Datenbanksprache SQL übernommen. Die Teile 1 u​nd 2 beschreiben d​en umgekehrten Weg, nämlich Java Klassen (Routines a​nd Types) i​n SQL Statements anzusprechen. Teil 1 u​nd 2 wurden a​ls SQL Teil 13 SQL Routines a​nd Types Using t​he Java Programming Language i​n SQL standardisiert.

Im Folgenden s​teht der Begriff SQLJ a​ls Synonym für SQLJ Part 0.

Mit SQLJ i​st Embedded SQL für Java definiert. Im Gegensatz d​azu stellt JDBC e​ine API bereit.

Format

Die eingebettete SQL-Anweisungen h​aben das folgende Format:

 #sql [[<context>]] { <SQL-Anweisung> };

Sie beginnen m​it der Zeichenfolge #sql, können mehrere Zeilen umfassen u​nd enden m​it einem Semikolon. Sie können Java-Variablen (:x) u​nd Ausdrücke :(y + z) enthalten.

Vor- und Nachteile

SQLJ bietet mehrere Vorteile:

  • die Programmierung ist im Vergleich zu JDBC wesentlich einfacher, da SQLJ direkt auf Variablen des umgebenden Java-Codes zugreifen kann.
  • im Falle von SQLJ für IBMs DB2 besteht eine bessere Authentifizierungskontrolle, da Benutzerrechte nicht auf Basis von Tabellen, sondern auf Basis von gebundenen SQLJ Profilen (Packages) geprüft werden, damit ist eine programmorientierte Berechtigung möglich.
  • Der SQLJ Translator überprüft die Syntax und Semantik von SQL-Anweisungen. Es besteht so die Möglichkeit, die Anweisungen gegen das Datenbankschema zu prüfen, wobei SQL-Fehler frühzeitig entdeckt und behoben werden können. Im Gegensatz hierzu werden bei Verwendung von JDBC Fehler erst zur Laufzeit erkannt.

Nachteile sind:

  • SQLJ-Programme müssen mittels eines Präprozessors in Java-Quelltext transformiert werden
  • die SQLJ Syntax wird von vielen Entwicklungsumgebungen nicht erkannt
  • SQLJ wird durch gängige Persistenz-Frameworks wie Hibernate nicht unterstützt
  • Der Präprozessor versteht, Stand Anfang 2006, noch keine Elemente der Java-Syntax, die mit den Versionen 1.4 (assert) und 5.0 (Generische Typen, Extended For Loop u. a.) eingeführt wurden.
  • Der Präprozessor lädt unter Umständen Klassen, von denen die zu übersetzende Klasse abhängt. Dadurch werden ggf. Klasseninitialisierer ausgeführt, was u. U. Nebenwirkungen auslöst oder die Übersetzungszeit verlängert.

Beispiele und Vergleich mit JDBC

Die folgenden Beispiele vergleichen SQLJ-Syntax m​it JDBC-Aufrufen:

JDBC SQLJ
Abfrage
PreparedStatement stmt = conn.prepareStatement(
   "SELECT LASTNAME"
 + " , FIRSTNAME"
 + " , 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);
  // Zeile drucken...
}
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;
  // Zeile drucken...
}
iter.close();
Abfrage, die genau eine Zeile liefert
PreparedStatement stmt = conn.prepareStatement(
    "SELECT MAX(SALARY), AVG(SALARY)"
  + " FROM DSN8710.EMP");
rs = statement.executeQuery();
if (!rs.next()) {
  // Fehler -- nichts gefunden
}
maxSalary = rs.getBigDecimal(1);
avgSalary = rs.getBigDecimal(2);
if (rs.next()) {
  // Fehler -- mehr als ein Treffer
}
rs.close();
stmt.close();
#sql [ctx] {
  SELECT MAX(SALARY), AVG(SALARY)
    INTO :maxSalary, :avgSalary
    FROM DSN8710.EMP
};
INSERT
PreparedStatement 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)
};
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. The authors of the article are listed here. Additional terms may apply for the media files, click on images to show image meta data.