Trigger

datasqill ermöglicht für bestimmte Funktionalitäten frei definierbare Trigger. Diese werden verwendet, um zu bestimmten Zeitpunkten (z.B. nach Aufbau einer Verbindung, nach dem Schreiben, usw.) bestimmte Aktivitäten in der Datenbank auszulösen, oder aber auch, um nicht standardisierte Funktionalitäten zu ermöglichen (z.B. Truncate Table). Zur Ausführung eines Triggers können mehrere Befehle ausgeführt werden. Diese werden in Statement Sets zusammengefasst. Trigger können auf unterschiedlichen Ebenen definiert werden:

  • Pro Connection- / Datenbanktyp in der Entität vv_datasqill_database_type_trigger
  • Pro Connection / Datenbank in der Entität vv_datasqill_database_trigger
  • Pro Transformation in der Entität vv_datasqill_action_trigger

Jede Tabelle enthält die ID, des referenzierten Objekts (Connectiontyp, Connection oder Transformation), sowie den Namen des Triggers trigger_name und den Namen des Statement Sets statement_set_name.

Triggerdefinitionen pro Transformation überschreiben Trigger pro Connection.

Triggerdefinitionen pro Connection überschreiben Trigger pro Connectiontyp.

Trigger einer vorherigen Hierarchie können gelöscht werden, indem man leere Trigger (statement_set_name leer oder NULL) angibt.

Jedes Modul definiert in der Entität vv_datasqill_module_trigger welche Trigger es ausführen kann.

Zusätzlich zu den Triggern, die vor oder nach einem Ereignis ausgelöst werden sollen, können auch "Instead of Trigger" definiert werden. Diese werden ausgeführt, wenn eine bestimmte Funktionalität benötigt wird. Derzeit wird nur der Trigger Instead of Truncate verwendet. Dieser wird aufgerufen, wenn eine komplette Tabelle geleert werden soll. Ist der Trigger nicht vorhanden, wird die Tabelle mit dem SQL DELETE-Befehl komplett geleert.

Triggerdefinition pro Connection oder Connectiontyp werden beim "Export von Connections" in der GUI mit gespeichert und beim Deployment in die datasqill Zielumgebung übertragen.

Triggerdefinition pro Action werden beim jeweiligen Arbeitsblatt (Sheet) mit gespeichert und beim Deployment vom Sheet in die datasqill Zielumgebung übertragen.

Statement Sets

Ein Statement Set enthält ein oder mehrere einzelne Befehle, die in der Datenbank ausgeführt werden. Er wird im Repository in der Entität vv_datasqill_statement_set abgelegt. Die Kombination aus dem Namen statement_set_name und der Reihenfolge sorting ergibt den gesamten Satz, der bei einem Trigger zur Auführung kommen kann.

Bei der Ausführung vom Befehl statement können 3 verschieden Methoden method gewählt werden. In der Spalte ignore_errors wird pro ausführender Befehl festgelegt, ob auftretende Fehler ignoriert werden soll.

Methode execute

Der angegebene Befehl statement wird als Java Statement mit der Methode executeUpdate ausgeführt.

Methode call

Der angegebene Befehl statement wird als Java CallableStatement mit der Methode execute ausgeführt. Ein der Datenbank entsprechender Aufruf muss verwendet werden. Bei vielen Datenbanken wird die Escape-Syntax unterstützt:

{call procedure_xy()}

Ansonsten muss das native Verfahren der Zieldatenbank verwendet werden.

Methode select statistics

Bei dem angegebenen Befehle statement handelt es sich um ein Select-Statement. Pro zurückkehrende Zeile von diesem Statement wird ein Eintrag in sqts_request_result eingefügt. Diese Methode wird verwendet um statistische Informationen über die Datenbank, bzw. die ausgeführten Befehle zu erhalten. Die folgenden Spaltennamen vom Select-Statement müssen verwendet werden:

  • stat_name: Name eines Statistikwertes. Wenn der Name in der Entität vv_sqts_result_type enthalten ist und das Flag log_enabled auf 'Y' steht, dann wird dieser Wert in sqts_request_result übertragen.
  • stat_value_numeric: Bei numerischen Werten der dazugehörige Wert (h2 Datentyp BIGINT).
  • stat_value_character: Bei Zeichenketten der dazugehörige Wert (h2 Datentyp VARCHAR). Wird derzeit noch nicht gespeichert.

Verwendung von Variablen

In den angegebenen Befehlen können folgende Variablen verwendet werden:

  • batch_instance_id: Laufende Nummer des aktuellen "Runs"
  • schedule_date: Start Datum und Uhrzeit des Batches im Format yyyy-MM-ddTHH:mm:ss:SSSZ
  • action_id: ID der aktuelle Transformation
  • request_id: Systemeindeutige ID dieser Ausführung
  • connection_id: Connection in der dieses Statement ausgeführt wird
  • module_start_timestamp: Start Datum und Uhrzeit in lokaler Zeit der Transformation im Format yyyy-MM-dd HH:mm:ss.SSS
  • module_start_datetime: Start Datum und Uhrzeit in lokaler Zeit der Transformation im Format yyyy-MM-dd HH:mm:ss
  • module_start_date: Start Datum in lokaler Zeit der Transformation im Format yyyy-MM-dd
  • module_utc_start_timestamp: Start Datum und Uhrzeit in UTC Zeit der Transformation im Format yyyy-MM-dd HH:mm:ss.SSS
  • module_utc_start_datetime: Start Datum und Uhrzeit in UTC Zeit der Transformation im Format yyyy-MM-dd HH:mm:ss
  • module_utc_start_date: Start Datum in UTC Zeit der Transformation im Format yyyy-MM-dd
  • target_connection_id: Connection der Zieltabelle
  • target_schema: Schemaname der Zieltabelle
  • target_schema_quoted: Schemaname der Zieltabelle in Anführungszeichen, falls Sonderzeichen enthalten sind
  • target_table: Name der Zieltabelle
  • target_table_quoted: Name der Zieltabelle in Anführungszeichen, falls Sonderzeichen enthalten sind
  • target_partition: Name der Zielpartition oder leere Zeichenkette, falls keine angegeben ist
  • target: Name der Zieltabelle, wenn Zielschema leer ist. Sonst Zielschema Punkt und Zieltabelle (schema.table)
  • sources: Liste aller Quellen. Pro Element gibt es die Spalten entsprechend eines Objekts in datasqill:
    • sqtsObjectId = sqts_object_id
    • sqtsObjectTypeId = 1 für Datenbankobjekte
    • serverId = Connection der Quelltabelle
    • objectOwner = Schema
    • objectName = Tabellenname
    • objectPartition = Partition
  • source_schema: Nur gesetzt, wenn es genau eine Quelle vom Typ Datenbankobjekt gibt. Dann Schemaname der Quelltabelle
  • source_table: Nur gesetzt, wenn es genau eine Quelle vom Typ Datenbankobjekt gibt. Dann Name der Quelltabelle
  • source_partition: Nur gesetzt, wenn es genau eine Quelle vom Typ Datenbankobjekt gibt. Dann Partition der Quelltabelle
  • iteration: Laufende Nummer der Iteration wenn es eine Loop-Query gibt. Sonst 1

datasqill verwendet zur Ersetzung der Variablen Freemarker. Hierbei ist Freemarker derart konfiguriert, das die Symbol nicht in spitzen sondern in eckigen Klammern angegeben werden. Die Variablen werden in geschweiften Klammern mit führendem Dollarzeichen angegeben.

Beispiele für Befehle:

Truncate einer Tabelle für Postgres

TRUNCATE TABLE ONLY ${target} RESTART IDENTITY

Vacuum einer Tabelle für Postgres

BEGIN; END WORK; VACUUM ANALYSE ${target}; END

Pro Quelldatenbankobjekt (sqtsObjectTypeId=1) in einer Oracledatenbank eine Grantfunktion mit Leserechten aufrufen und für die Zieltabelle eine Grantfunktion mit Schreibrechten

BEGIN
[#list sources as src][#if "${src.sqtsObjectTypeId}" == "1" && "${src.serverId}" == "${connection_id}"]
  dsrt_grant_object('${src.objectOwner}', '${src.objectName}', 'SELECT');[/#if][/#list][#if target_table?has_content && "${target_connection_id}" == "${connection_id}"]
  dsrt_grant_object('${target_schema}', '${target_table}', 'SELECT,INSERT,UPDATE,DELETE');[#else]NULL;[/#if]
END;

Lesen der Statistiken des verwendeten Tempspaces und der eindeutigen Session Nummer für Oracle (Methode select statistics)

SELECT 'tempspace' stat_name
     , MAX(ses_hist.temp_space_allocated) stat_value_numeric
     , NULL stat_value_character
  FROM (SELECT NVL(qc_session_id, session_id) session_id
             , NVL(qc_session_serial#, session_serial#) session_serial#
             , sample_id
             , SUM(temp_space_allocated) temp_space_allocated
          FROM v$active_session_history
         GROUP BY NVL(qc_session_id, session_id)
                , NVL(qc_session_serial#, session_serial#)
                , sample_id
       ) ses_hist
     , v$session ses
 WHERE ses.sid = ses_hist.session_id(+)
   AND ses.serial# = ses_hist.session_serial#(+)
   AND ses.audsid = SYS_CONTEXT('USERENV', 'SESSIONID')
UNION ALL
SELECT 'session_id' stat_name
     , TO_NUMBER(SYS_CONTEXT('USERENV', 'SESSIONID')) stat_value_numeric
     , NULL stat_value_character
  FROM dual

Lesen der eindeutigen Session Nummer für Exasol (Methode select statistics)

SELECT 'session_id' stat_name
     , CURRENT_SESSION stat_value_numeric
     , NULL stat_value_character

Dafür muss das Loggen der Statistic in sqts_request_result eingeschaltet werden

INSERT INTO vv_sqts_result_type(result_type_id, result_type_name, result_type_desc, data_type, log_enabled)
SELECT NVL(result_type_id, max_result_type_id + 1) result_type_id
     , 'session_id' result_type_name
     , 'Database Session or Transaction ID' result_type_desc
     , 'N' data_type
     , 'Y' log_enabled
  FROM (SELECT COUNT(*) cnt
             , MAX(result_type_id) result_type_id
          FROM vv_sqts_result_type
         WHERE result_type_name = 'session_id'
       )
     , (SELECT MAX(result_type_id) max_result_type_id
          FROM vd_sqts_result_type
         WHERE result_type_id < 1000
       )