Temporäre Tabellen in Db2 for i – effizient, flexibel, aber bitte mit Plan

Futuristische Infografik zu temporären Tabellen in Db2 for i mit SESSION, QTEMP, CTE, TRUNCATE und Index-Beispielen.
Temporäre Tabellen in Db2 for i: SESSION, QTEMP, CTE, TRUNCATE und Indizes in der Praxis.
Temporäre Tabellen sind echte Alltagshelden in Db2 for i. Sie speichern Zwischenergebnisse nur für den aktuellen Anwendungskontext – auf IBM i also typischerweise für die laufende Verbindung bzw. den aktuellen Job. Damit entlasten sie produktive Datenstrukturen und machen SQL-Prozesse deutlich übersichtlicher. Gleichzeitig sind sie kein magischer Performance-Turbo. Ob sie schneller sind als CTEs, Views oder persistente Tabellen, hängt stark vom konkreten Workload, den Datenmengen, den Zugriffsmustern, vorhandenen Indizes und dem SQL-Plan ab.

Was sind temporäre Tabellen?

Kurz gesagt: Temporäre Tabellen speichern Daten nur während des aktuellen Anwendungskontexts. Auf IBM i entspricht das in der Praxis meist der laufenden Verbindung bzw. dem aktuellen Job. Wenn dieser Kontext endet, verschwinden Definition und Inhalt automatisch – ideal für flüchtige Zwischenstände, Reports, Staging-Schritte und komplexere SQL-Abläufe.

Auf IBM i arbeitest Du mit DECLARE GLOBAL TEMPORARY TABLE (kurz: DGTT). Die Tabelle ist nicht persistent, erscheint nicht im normalen Systemkatalog und kann nicht mit anderen Anwendungskontexten geteilt werden. Jede Verbindung bzw. jeder relevante Job-Kontext erhält seine eigene Instanz.

Technisches Fundament

Der Tabellenname muss dem Schema SESSION zugeordnet sein. Db2 for i legt das Objekt intern in QTEMP an. In SQL sprichst Du die Tabelle jedoch normalerweise über SESSION.DEIN_NAME an.

SQL · einfache DGTT
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_EMP (
    EMPNO CHAR(6) NOT NULL,
    SALARY DECIMAL(10, 2),
    DEPTNO CHAR(3)
)
WITH REPLACE
ON COMMIT PRESERVE ROWS
NOT LOGGED;

WITH REPLACE ersetzt eine bereits vorhandene gleichnamige temporäre Tabelle im selben Anwendungskontext und löscht dabei deren bisherige Zeilen. ON COMMIT PRESERVE ROWS bewahrt die Zeilen nach einem Commit. Ohne diese Option gilt der Standard ON COMMIT DELETE ROWS – die Zeilen können beim Commit also verschwinden, sofern kein abhängiger WITH HOLD-Cursor offen ist. NOT LOGGED reduziert den Logging-Overhead, bedeutet aber auch: Änderungen an dieser Tabelle werden bei einem Rollback nicht wie normale Tabellenänderungen zurückgenommen.

DGTT auf IBM i: SESSION und QTEMP

Ein häufiges Missverständnis: Weil die Tabelle technisch in QTEMP landet, deklariert man sie schnell auch so. Das ist bei DECLARE GLOBAL TEMPORARY TABLE auf IBM i jedoch nicht der richtige Weg. Der Qualifier ist SESSION. Wird kein Qualifier angegeben, nimmt Db2 for i implizit SESSION an.

Achtung: DECLARE GLOBAL TEMPORARY TABLE QTEMP.MY_TEMP ... ist für eine DGTT nicht korrekt. Wenn Du einen Qualifier angibst, muss er SESSION sein. Alternativ kannst Du den Qualifier weglassen; Db2 for i nimmt dann implizit SESSION an.

Namensauflösung

Wenn eine DGTT existiert, löst SESSION.TEMP_EMP auf diese temporäre Tabelle auf. Existiert sie im aktuellen Anwendungskontext nicht, behandelt Db2 for i den Namen nicht als DGTT-Referenz und kann ihn als permanente Tabelle im Schema SESSION auflösen. In Stored Procedures und RPG-Programmen ist es deshalb sicherer, die temporäre Tabelle vor der Nutzung eindeutig zu deklarieren.

Optional: FOR SYSTEM NAME

Wenn Du mit langen SQL-Namen arbeitest, kannst Du bei Bedarf zusätzlich einen IBM-i-Systemnamen vergeben. Dieser Systemname ist auf zehn Zeichen begrenzt und kann in sehr systemnahen Szenarien hilfreich sein. Für normale SQL-Nutzung ist die Option aber meist nicht nötig.

SQL · DGTT mit Systemname
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_EMPLOYEE_REPORT (
    EMPNO CHAR(6),
    DEPTNO CHAR(3),
    TOTAL_SALARY DECIMAL(15,2)
)
FOR SYSTEM NAME TEMPEMP01
WITH REPLACE
ON COMMIT PRESERVE ROWS
NOT LOGGED;

SQL-Beispiele zum Nachbauen

1. Struktur aus einer bestehenden Tabelle ableiten

Du kannst die Struktur einer DGTT aus einer Abfrage ableiten oder direkt von einer bestehenden Tabelle übernehmen:

SQL · Struktur übernehmen
-- Variante A: Mit SELECT
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_EMP AS (
  SELECT EMPNO, SALARY, DEPTNO
  FROM MYLIB.EMPLOYEES
)
WITH NO DATA
ON COMMIT PRESERVE ROWS
NOT LOGGED;

-- Variante B: Mit LIKE (sehr sauber)
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_EMP 
LIKE MYLIB.EMPLOYEES
WITH REPLACE
ON COMMIT PRESERVE ROWS
NOT LOGGED;

2. CTE für ein einmaliges Zwischenergebnis

Wenn Du ein Zwischenergebnis nur innerhalb einer einzelnen SQL-Anweisung brauchst, ist eine CTE oft eleganter:

SQL · CTE
WITH TempSales AS (
  SELECT ORDERID, SUM(AMOUNT) AS TOTAL
  FROM MYLIB.SALES
  GROUP BY ORDERID
)
SELECT *
FROM TempSales
WHERE TOTAL > 1000;

3. CTE und temporäre Tabelle kombinieren

Für mehrstufige Verarbeitung kann eine DGTT sinnvoll sein: Einmal befüllen, mehrfach auswerten, optional indizieren.

SQL · CTE in DGTT schreiben
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_AVGSAL (
  DEPTNO CHAR(3),
  AVG_SAL DECIMAL(11,2)
)
WITH REPLACE
ON COMMIT PRESERVE ROWS
NOT LOGGED;

INSERT INTO SESSION.TEMP_AVGSAL
WITH Aggregated AS (
  SELECT DEPTNO, DECIMAL(AVG(SALARY), 11, 2) AS AVG_SAL
  FROM MYLIB.EMPLOYEES
  GROUP BY DEPTNO
)
SELECT DEPTNO, AVG_SAL
FROM Aggregated;

TRUNCATE TABLE vs. WITH REPLACE

WITH REPLACE ist praktisch, wenn Du eine temporäre Tabelle robust neu deklarieren möchtest. Für wiederholte Verarbeitungsschritte mit gleicher Struktur ist es jedoch meist sauberer, die Tabelle einmal zu erstellen und danach mit TRUNCATE TABLE zu leeren.

Wann TRUNCATE?

  • Die Struktur bleibt gleich.
  • Die Tabelle wird mehrfach im selben Job oder in derselben Procedure befüllt.
  • Vorhandene Indizes auf der temporären Tabelle sollen erhalten bleiben.
  • Du willst den Overhead durch wiederholtes Deklarieren reduzieren.
SQL · wiederverwendbare DGTT
DECLARE GLOBAL TEMPORARY TABLE SESSION.MONTHLY_SALES (
    MONTH_ID INT,
    TOTAL_SALES DECIMAL(15,2)
)
WITH REPLACE
ON COMMIT PRESERVE ROWS
NOT LOGGED;

-- Januar laden
INSERT INTO SESSION.MONTHLY_SALES
SELECT 1, SUM(AMOUNT)
FROM MYLIB.SALES
WHERE ORDER_DATE BETWEEN DATE('2026-01-01') AND DATE('2026-01-31');

SELECT * FROM SESSION.MONTHLY_SALES;

-- Tabelle für den nächsten Schritt leeren
TRUNCATE TABLE SESSION.MONTHLY_SALES REUSE STORAGE;

-- Februar laden
INSERT INTO SESSION.MONTHLY_SALES
SELECT 2, SUM(AMOUNT)
FROM MYLIB.SALES
WHERE ORDER_DATE BETWEEN DATE('2026-02-01') AND DATE('2026-02-28');
Praxis-Tipp: REUSE STORAGE ist bei wiederholtem Befüllen meist sinnvoll, weil der bereits zugewiesene Speicher weiterverwendet werden kann. Der Standard ist DROP STORAGE; dabei wird Speicher wieder freigegeben. Achtung bei IMMEDIATE: Ein TRUNCATE TABLE ... IMMEDIATE kann nicht per Rollback rückgängig gemacht werden. Ohne IMMEDIATE kann ein Rollback den Truncate-Vorgang zurücknehmen. Wie immer gilt: im eigenen Job messen.

Indizes auf temporären Tabellen

Temporäre Tabellen sind nicht automatisch gut optimiert. Wenn Du größere Zwischenergebnisse mehrfach filterst, joinst oder sortierst, kann ein Index auf der DGTT helfen.

SQL · Index auf DGTT
CREATE INDEX SESSION.IDX_TEMP_EMP_DEPT
ON SESSION.TEMP_EMP (DEPTNO, EMPNO);
Nicht übertreiben: Ein Index kostet beim Aufbau Zeit und bei Inserts zusätzlichen Aufwand. Für kleine temporäre Datenmengen ist er oft unnötig. Bei größeren Zwischenergebnissen mit wiederholten Joins oder Filtern kann er jedoch den entscheidenden Unterschied machen.

Wann solltest Du temporäre Tabellen einsetzen?

  • Mehrstufige Verarbeitung: Wenn ein Zwischenergebnis mehrfach gebraucht wird.
  • Batch- und Reporting-Jobs: Wenn ein Job Daten sammelt, verdichtet und anschließend auswertet.
  • Komplexe SQL-Flows: Wenn eine einzelne Monster-Abfrage unlesbar oder schwer zu testen wird.
  • Session-Isolation: Wenn parallele Jobs eigene Arbeitsdaten brauchen, ohne sich gegenseitig zu stören.
  • Ad-hoc-Analyse: Wenn Du in ACS oder Navigator kurz mit Zwischenständen arbeiten möchtest.
Mythos: „Temporäre Tabellen sind immer schneller.“
Nein. Manchmal ist eine CTE schneller, manchmal eine View, manchmal eine persistente Arbeitstabelle mit sauberem Index. Temporäre Tabellen sind ein Werkzeug – kein Zauberstab.

Praxisbeispiel: Monatsbericht für Verkaufsdaten

Szenario: Ein Unternehmen auf IBM i erstellt monatlich einen Bericht über Umsätze pro Abteilung. Die Rohdaten liegen in MYLIB.SALES. Statt dieselbe Aggregation mehrfach auszuführen, wird das verdichtete Ergebnis in einer temporären Tabelle gespeichert.

SQL · Monatsbericht
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_SALES_REPORT (
    DEPTNO CHAR(3),
    TOTAL_SALES DECIMAL(15,2)
)
WITH REPLACE
ON COMMIT PRESERVE ROWS
NOT LOGGED;

INSERT INTO SESSION.TEMP_SALES_REPORT
SELECT DEPTNO, SUM(AMOUNT) AS TOTAL_SALES
FROM MYLIB.SALES
WHERE ORDER_DATE BETWEEN DATE('2026-05-01') AND DATE('2026-05-31')
GROUP BY DEPTNO;

CREATE INDEX SESSION.IDX_TEMP_SALES_DEPT
ON SESSION.TEMP_SALES_REPORT (DEPTNO);

SELECT *
FROM SESSION.TEMP_SALES_REPORT
ORDER BY TOTAL_SALES DESC;

Vorteile in diesem Szenario

  • Lesbarkeit: Die Aggregation ist klar von der Ausgabe getrennt.
  • Wiederverwendung: Dasselbe Zwischenergebnis kann für mehrere Auswertungen genutzt werden.
  • Isolation: Jeder Job arbeitet mit seiner eigenen temporären Tabelle.
  • Optionales Tuning: Bei Bedarf kann ein Index auf der temporären Tabelle erstellt werden.

Nachteile und Grenzen

  • Zusätzlicher Schritt: Die Tabelle muss befüllt werden. Das lohnt sich nicht für jedes kleine SELECT.
  • Planung nötig: Ohne Index oder mit falschem Index kann eine DGTT langsam bleiben.
  • Flüchtigkeit: Nach Ende des Anwendungskontexts ist alles weg. Für Audit, Debugging oder Wiederanlauf brauchst Du andere Mechanismen.
  • Commit-Verhalten: Ohne ON COMMIT PRESERVE ROWS kann ein Commit Deine Zeilen löschen.

Vergleich: DGTT, CTE, View, persistente Tabelle

Die folgende Tabelle ist bewusst qualitativ gehalten. Feste Millisekundenwerte sind ohne konkrete Hardware, Datenmenge, PTF-Stand, Jobkonfiguration und SQL-Plan schnell irreführend.

Aspekt DGTT / temporäre Tabelle CTE View Persistente Arbeitstabelle
Lebensdauer Session / Job Nur innerhalb einer SQL-Anweisung Permanent definierte Abfragelogik Permanent, bis manuell bereinigt
Gut für Mehrfach genutzte Zwischenergebnisse Lesbare Einmal-Abfragen Wiederverwendbare SQL-Sicht Große, wiederkehrende Prozesse mit Wiederanlaufbedarf
Index möglich? Ja, der Index muss in SESSION oder QTEMP erstellt werden. Nicht direkt auf die CTE selbst Nicht wie bei einer Tabelle; Optimizer entscheidet Ja, normal persistent
Recovery / Audit Schwach, weil flüchtig Nicht anwendbar Keine eigenen Daten Stark, wenn sauber journalisiert
Typischer Stolperstein Commit löscht Zeilen, wenn PRESERVE ROWS fehlt Kann bei mehrfacher Nutzung unübersichtlich werden Kann komplexe Pläne verstecken Bereinigung, Sperren, Journaling, Berechtigungen

Db2 ist nicht gleich Db2: IBM i, LUW, z/OS

Bei temporären Tabellen ist die Plattform wichtig. Db2 for i, Db2 LUW und Db2 for z/OS verwenden teilweise ähnliche Begriffe, aber nicht immer dieselbe Syntax. Für IBM i ist DECLARE GLOBAL TEMPORARY TABLE der zentrale Weg. Syntax und Verhalten aus LUW/z/OS-Artikeln solltest Du nicht ungeprüft auf IBM i übertragen.

Merksatz: Auf IBM i zählen bei temporären Tabellen die Plattformdetails: SESSION, QTEMP, Commit-Verhalten, NOT LOGGED und echte Messungen im jeweiligen Job.

Best Practices für IBM i Developer

  • Verwende konsequent SESSION für DGTTs.
  • Setze ON COMMIT PRESERVE ROWS, wenn die Daten nach Commit erhalten bleiben sollen.
  • Nutze NOT LOGGED bewusst: weniger Logging-Overhead, aber Änderungen werden bei Rollback nicht wie bei normalen Tabellenänderungen zurückgenommen.
  • Verwende TRUNCATE TABLE, wenn Du eine temporäre Tabelle mit gleicher Struktur wiederverwenden möchtest.
  • Erstelle Indizes nur, wenn sie durch wiederholte Filter, Joins oder Sortierungen wirklich helfen.
  • Miss mit ACS Visual Explain, IBM i Navigator, Plan Cache oder Datenbank-Monitoring.
  • Droppe temporäre Tabellen in langen Prozeduren oder wiederverwendeten Verbindungen explizit, wenn Name, Speicher oder Zustand gezielt freigegeben werden sollen.
SQL · optionales Cleanup
DROP TABLE SESSION.TEMP_SALES_REPORT;

Fazit

Temporäre Tabellen in Db2 for i sind stark, wenn Du sie gezielt einsetzt: für verbindungs- bzw. jobbezogene Zwischenergebnisse, Reports, Batch-Prozesse und mehrstufige SQL-Logik. Wichtig sind die Details: In SQL wird die DGTT über SESSION angesprochen, auch wenn Db2 for i sie intern in QTEMP anlegt. Dazu kommen bewusstes Commit- und Rollback-Verhalten, NOT LOGGED mit Verstand, optional TRUNCATE TABLE zur Wiederverwendung und Indizes nur dort, wo sie messbar helfen. Die beste Regel bleibt: nicht glauben, messen.

Quellen

Glossar

Begriffe und Abkürzungen aus dem Artikel – kompakt erklärt.

ACS (Access Client Solutions)
IBM i Client-Tool für Administration, SQL-Konsole und Systemzugriff.
Application Process
In der IBM-Dokumentation der Kontext, in dem eine temporäre Tabelle deklariert und genutzt wird; auf IBM i praktisch oft eng mit Job/Verbindung verbunden.
AS/400
Historischer Name der Plattform, aus der IBM i hervorgegangen ist.
CTE (Common Table Expression)
WITH-Konstrukt für Zwischenergebnisse innerhalb einer einzelnen SQL-Anweisung.
Db2 for i
Die integrierte relationale Datenbank der IBM-i-Plattform.
DGTT
Declared Global Temporary Table; temporäre Tabelle, die mit DECLARE GLOBAL TEMPORARY TABLE erstellt wird.
FOR SYSTEM NAME
Option für einen IBM-i-Systemnamen (max. 10 Zeichen), nützlich bei Namenslimits oder systemnahen Zugriffen.
IBM i
Betriebssystem und Plattform auf IBM Power Systems, früher u. a. iSeries/AS/400.
Index
Datenstruktur zur Beschleunigung von Such-, Join- und Sortieroperationen.
Journaling
Protokollierung von Datenänderungen für Recovery, Audit und Transaktionssicherheit.
NOT LOGGED
DGTT-Option zur Reduzierung von Logging-Overhead; Änderungen an der temporären Tabelle werden bei Rollback nicht wie normale Tabellenänderungen zurückgenommen.
Optimizer
Komponente, die SQL-Ausführungspläne auswählt.
Plan Cache
Zwischenspeicher für SQL-Ausführungspläne.
QTEMP
Job-spezifische temporäre Bibliothek auf IBM i.
RPG / SQLRPGLE
Programmiersprache bzw. RPG-Variante mit eingebettetem SQL, häufig im IBM-i-Umfeld.
SESSION
SQL-Schema für deklarierte temporäre Tabellen.
TRUNCATE TABLE
SQL-Anweisung zum schnellen Leeren einer Tabelle, ohne die Tabellenstruktur zu entfernen.
WITH REPLACE
DGTT-Option, mit der eine gleichnamige temporäre Tabelle in derselben Session ersetzt wird.

Transparenzhinweis


Transparenzhinweis:
Die Inhalte auf tiny-tool.de werden sorgfältig recherchiert, redaktionell geprüft und regelmäßig aktualisiert. Quellen und Zitate werden möglichst nachvollziehbar angegeben. Dennoch übernehmen wir keine Garantie für Richtigkeit, Vollständigkeit oder Aktualität der bereitgestellten Informationen. Irrtümer sind nicht ausgeschlossen.

Redaktion und Einsatz von KI: Bei der Erstellung von Inhalten können digitale Werkzeuge – darunter auch KI-basierte Assistenzsysteme – unterstützend eingesetzt werden, etwa bei Recherche, Strukturierung, sprachlicher Überarbeitung, Übersetzung, Codeanalyse oder visueller Gestaltung. Veröffentlichte Inhalte werden redaktionell geprüft, bearbeitet und von Guido Zeuner freigegeben. Auswahl, Einordnung und Veröffentlichung liegen beim Menschen. KI-Ausgaben gelten nicht als eigenständige Quellen. KI-Systeme sind keine verantwortlichen Autoren oder Redakteure. Weitere Informationen zu Texten, Bildern, Videos und digitalen Personas findest du auf unserer Seite Transparenz beim Einsatz von Künstlicher Intelligenz.

Reichweitenmessung (VG WORT / METIS): Zur Ermittlung der Reichweite einzelner Texte können Zählmarken der VG WORT eingesetzt werden. Im Rahmen der METIS-Zugriffszählung kann eine Client-ID gebildet und ein sogenanntes „METIS Session Cookie“ gesetzt werden. Die Messung dient der statistischen Ermittlung von Textzugriffen und als Grundlage für mögliche Ausschüttungen der VG WORT. Nach Angaben der VG WORT werden dabei keine personenbezogenen Nutzungsprofile erstellt; die Messung dient nicht der Werbung oder dem Marketing-Tracking. Weitere Informationen findest du in unseren Datenschutzhinweisen.

Bitte beachte: Die Inhalte dienen ausschließlich der allgemeinen Information und stellen keine fachliche Beratung dar, insbesondere keine rechtliche, steuerliche, medizinische, technische oder finanzielle Beratung. Die Nutzung der Inhalte erfolgt auf eigene Verantwortung.

Werbung und Affiliate-Links: Einige Beiträge können werbliche Hinweise oder sogenannte Affiliate-Links enthalten. Diese werden entsprechend gekennzeichnet. Beim Klick entstehen dir keine zusätzlichen Kosten; wir erhalten gegebenenfalls eine kleine Provision.

Markenrechtlicher Hinweis: Alle Markennamen, Logos und Produktbezeichnungen sind Eigentum der jeweiligen Rechteinhaber und werden ausschließlich zur Identifikation und Beschreibung verwendet. Eine Verbindung zu den genannten Unternehmen besteht nur, wenn dies ausdrücklich angegeben wird.

Externe Links: Diese Website enthält Verweise auf externe Websites Dritter. Trotz sorgfältiger Prüfung übernehmen wir keine Verantwortung für deren Inhalte. Bei Bekanntwerden rechtswidriger Inhalte werden entsprechende Links geprüft und gegebenenfalls entfernt.