Die Erfassung der Transformationen erfolgt in Arbeitsblättern (Sheets). Diese werden in Verzeichnissen organisiert.
Eine einzelne Transformation benötigt Quellen und Ziele und verwendet ein bestimmtes Modul.
In Arbeitsblättern werden Transformationen zusammengefasst.
Arbeitsblätter sind die kleinste Deploymenteinheit.
Ein Objekt definiert sich aus der Objektart und zusätzlichen Eigenschaften, wie Connection, Namen, Schema, Pfad, etc.
Außerdem kann man auf Objektebene bestimmen, ob die Verbindung zu anderen Sheets als Abhängigkeit berücksichtigt werden soll oder nicht.
Dieses konfiguriert man in der GUI in dem Feld Dependency. In diesem Feld stellt man auf Wait = "Auf Transformationen aus anderen Sheets warten" oder auf Ignore = "Nicht warten".
Zusätzlich kann man im Objekteditor die Metadaten von der angegebenen Connection refreshen.
Weiterhin kann man sich bei Datenbankobjekten ein (Export-) Skript generieren lassen, welches das Objekt beschreibt. Dieses Script kann man verwenden, um sich das DDL für die Anlage des Objekts zu erzeugen. Man kann Auszüge aus dem Skript direkt auf der Zieldatenbank ausführen, oder für die Definition von Artifakten verwenden.
Welcher Code dabei generiert wird erfolgt an Hand eines freemarker Templates. Dieses Template ist in der Tabelle vv_sqts_config_global definiert:
Typ | config_key1 | config_key2 | config_key3 | config_key4 |
---|---|---|---|---|
Export | VARIABLE | Template | TABLE_SCRIPT | EXPORT |
Es gibt jeweils zwei Sets von Variablen. Der erste Set bietet die unten angegebenen Variablen. Ein weiterer Set ist für die Basistabelle, falls es sich um ein Objekt handelt, welches auf genau ein anderes Objekt basiert (Für Views, die genau eine Tabelle als Quelle haben). Bei diesem Set haben alle Variablen den Prefix BASE_. Gibt es exakt ein Objekt auf den das Objekt basiert, dann wird dieser Set mit den Informationen der Basistabelle befüllt. Ansonsten entspricht dieser Set dem ersten Set.
Es werden im Freemarker folgende Variablen zur Verfügung gestellt:
Variable | Datentyp | Bedeutung |
---|---|---|
DATABASE_ID | Number | Die Connection des Objekts |
SCHEMA_NAME | String | Der Name des Schemas |
OBJECT_NAME | String | Der Name des Objekts |
OBJECT_TYPE | String | Der Objekttyp. Dereit entweder TABLE oder VIEW |
PK_NAME | String | Der Name des Primärschlüssels |
OBJECT_COMMENT | String | Der Objektkommentar |
SCHEMA_NAME_LOWER | String | Derzeit nicht unterstützt |
OBJECT_NAME_LOWER | String | Derzeit nicht unterstützt |
columns | Liste | Liste der Spalten des Objekts |
Hierbei hat jedes Objekt eine Liste von Namen und deren Werten. Folgende Namen sind verfügbar:
Name | Datentyp | Bedeutung |
---|---|---|
DATABASE_ID | Number | Die Connection des Objekts |
SCHEMA_NAME | String | Der Name des Schemas |
OBJECT_NAME | String | Der Name des Objekts |
COLUMN_NAME | String | Der Name der Spalte |
COLUMN_POSITION | Number | Position der Spalte innerhalb des Objekts |
COLUMN_TYPE | Number | Der Datentype |
COLUMN_PK_POSITION | Number | Wenn nicht null Position im Primary Key |
COLUMN_COMMENT | String | Der Spaltenkommentar |
COLUMN_IS_NULLABLE | CHAR | "Y" Nulls sind erlaubt, "N" nicht |
COLUMN_SOURCE_TYPE | String | Der Datentyp, wie im Quellsystem angegeben |
SCHEMA_NAME_LOWER | String | Derzeit nicht unterstützt |
OBJECT_NAME_LOWER | String | Derzeit nicht unterstützt |
COLUMN_NAME_LOWER | String | Derzeit nicht unterstützt |
Ein Beispiel, um den vollen Namen des Objekts name für die weitere Verwendung bereitzustellen:
[#if SCHEMA_NAME?has_content]
[#assign schema=SCHEMA_NAME?lower_case + "."]
[#else]
[#assign schema=""]
[/#if]
[#assign object=OBJECT_NAME?lower_case]
[#assign name=schema+object]
Analog für das Basisobjekt:
[#if BASE_SCHEMA_NAME?has_content]
[#assign base_schema=BASE_SCHEMA_NAME?lower_case + "."]
[#else]
[#assign base_schema=""]
[/#if]
[#assign base_object=BASE_OBJECT_NAME?lower_case]
[#assign base_name=base_schema + base_object]
Versionierte Tabellen erkennen:
[#-- base_tv and base_nv are placeholder for the versioned / non versioned table name with schema --]
[#assign base_tv=base_schema +base_object]
[#assign base_nv=base_schema +base_object]
[#if base_name?starts_with("tv_")]
[#assign base_nv=base_schema + base_object[3..]]
[#else]
[#assign base_tv=base_schema + "tv_" + base_object]
[/#if]
Die Spalten erkennen, die nicht zur Historisierung / Versionierung gehören
[#-- list of historize columns --]
[#assign hist_cols = ["upd_by", "ins_by", "is_latest_period","last_changed_dt", "valid_from_dt", "invalid_from_dt", "is_current_and_active", "is_deleted"]]
[#-- generate the list data_cols with all columns which are not sqdv columns --]
[#assign data_cols = []]
[#list baseColumns as col]
[#if !(col["COLUMN_NAME"]?lower_case?starts_with("sqdv_")) && !hist_cols?seq_contains(col["COLUMN_NAME"]?lower_case)]
[#assign data_cols += [col] ]
[/#if]
[/#list]
Aus den Primary Key Spalten, die Spalten herausfltern, die nicht Teil der versionierung sind
[#-- generate the list pkCols with all primary key columns which are not sqdv columns --]
[#assign pkCols = []]
[#list baseColumns as col]
[#if col["COLUMN_PK_POSITION"]?? && !(col["COLUMN_NAME"]?lower_case?starts_with("sqdv_")) && !hist_cols?seq_contains(col["COLUMN_NAME"]?lower_case)]
[#assign pkCols += [col] ]
[/#if]
[/#list]
[#assign pkCols = pkCols?sort_by("COLUMN_PK_POSITION")]
Eine Funktion, um sich die Spaltentypen für die Zielumgebung aufzubereiten
[#function toTargetType columType]
[#local colType = columType?upper_case]
[#local pos = colType?index_of("(")]
[#if pos != -1]
[#local colTypeFirst = colType?substring(0, pos)?trim]
[#local colTypeLast = colType?substring(pos)?trim]
[#local colTypeLast = colTypeLast?replace(" CHAR", "")?replace(" BYTE", "")]
[#else]
[#local colTypeFirst = colType?trim]
[#local colTypeLast = ""]
[/#if]
[#if ["BIGINT", "INTEGER", "SMALLINT", "TINYINT"]?seq_contains(colTypeFirst)]
[#local colTypeFirst = "INT"]
[#elseif ["TIMESTAMP", "TIMESTAMP WITHOUT TIME ZONE"]?seq_contains(colTypeFirst)]
[#local colTypeFirst = "DATETIME"]
[#elseif ["VARCHAR2", "CHARACTER VARYING"]?seq_contains(colTypeFirst)]
[#local colTypeFirst = "VARCHAR"]
[#elseif ["CHARACTER"]?seq_contains(colTypeFirst)]
[#local colTypeFirst = "CHAR"]
[#elseif ["NUMBER", "NUMERIC"]?seq_contains(colTypeFirst) && colTypeLast=""]
[#local colTypeFirst = "DECIMAL(15,2)"]
[#elseif ["NUMBER", "NUMERIC"]?seq_contains(colTypeFirst)]
[#local colTypeFirst = "DECIMAL"]
[#elseif ["CLOB", "TEXT"]?seq_contains(colTypeFirst)]
[#local colTypeFirst = "VARCHAR(MAX)"]
[#local colTypeLast = ""]
[/#if]
[#return colTypeFirst + colTypeLast]
[/#function]
Die Ausgabe der versionierten Tabelle für nicht SQDV-versionierten Tabellen
DROP TABLE IF EXISTS ${base_tv};
-- Versioned table with data types of target database
CREATE TABLE ${base_tv} (
[#list data_cols as col]${col["COLUMN_NAME"]?lower_case} ${toTargetType(col["COLUMN_TYPE"])}[#if col["COLUMN_IS_NULLABLE"] == 'N'] NOT NULL[/#if][#sep]
, [/#list]
, is_latest_period CHAR(1) NOT NULL
, is_current_and_active CHAR(1) NOT NULL
, is_deleted CHAR(1) NOT NULL
, last_changed_dt DATETIME NOT NULL
, valid_from_dt DATETIME NOT NULL
, invalid_from_dt DATETIME NOT NULL [#if pkCols?size > 0]
, PRIMARY KEY([#list pkCols as pk]${pk["COLUMN_NAME"]?lower_case}, [/#list]invalid_from_dt)[/#if]
);