SQL-Builder

Der SQL-Builder (OutlookSync.SqlBuilder.pas) generiert SELECT-, INSERT- und UPDATE-Statements aus der Mapping-Konfiguration.

Alias-Konventionen

Alias Bedeutung Beispiel
r Root-Tabelle FROM [STAP] r
jN N-te Relation (Index in Relations-Array) j4 = Relations[4]
fN N-ter gefilterter 1:N-JOIN f1 = erster fsRelated
_DbPK Root-PK im SELECT r.[IDSTAP] AS [_DbPK]
_PK_jN Hidden PK einer Relation (für Write-Back) j0.[IDSTAdr] AS [_PK_j0]
_PK_fN Hidden PK eines gefilterten JOINs f1.[IDSTTK] AS [_PK_f1]

Generiertes SQL — Beispiel

Für ein Mapping mit Wurzeltabelle STAP, einer Relation zu STAdr und gefilterten Feldern aus STTK:

SELECT
    r.[IDSTAP]     AS [_DbPK],
    r.[VN]         AS [FirstName],
    r.[NN]         AS [LastName],
    j0.[Str]       AS [BusinessAddressStreet],
    j0.[IDSTAdr]   AS [_PK_j0],
    f1.[B]         AS [Email1Address],
    f1.[IDSTTK]    AS [_PK_f1]
FROM [STAP] r
LEFT JOIN [STAdr] j0
    ON j0.[IDSTAP] = r.[IDSTAP]
OUTER APPLY (
    SELECT TOP 1 t.[B], t.[IDSTTK]
    FROM [STTK] t
    WHERE t.[IDSTAP] = r.[IDSTAP]
      AND t.[TKArt] = :P0
) f1

Erklärung

  • r — Alias für die Wurzeltabelle STAP
  • j0LEFT JOIN auf STAdr (1:1-Relation, Index 0)
  • f1OUTER APPLY mit TOP 1 auf STTK (gefilterte 1:N-Relation)
  • :P0 — Parametrisierter Filter-Wert (TKArt = 170)
  • _DbPK, _PK_j0, _PK_f1 — Hidden PK-Spalten für Write-Back

INSERT mit OUTPUT INSERTED

INSERT INTO [STAP] ([VN], [NN])
OUTPUT INSERTED.[IDSTAP]
VALUES (:P0, :P1)

Der generierte Primärschlüssel wird über OUTPUT INSERTED zurückgegeben und für das Fill-Back verwendet.


CopyColumns — Denormalisierte Parent-Spalten

Manche Child-Tabellen enthalten NOT-NULL-Spalten, die denormalisiert aus der Wurzeltabelle stammen (z.B. STTK.IDST = STAP.IDST). Das Mapping definiert diese über copyColumns im Relation-Objekt.

Beim INSERT in eine Child-Tabelle werden die CopyColumns per Subquery aus der Root-Tabelle aufgelöst:

INSERT INTO [STTK] ([IDST], [IDSTAP], [TKArt], [Wert])
VALUES (
  (SELECT [IDST] FROM [STAP] WHERE [IDSTAP] = :FK),
  :FK, :FV, :P0
)

Erklärung

  • :FK — Primärschlüssel des Root-Datensatzes (wird vom INSERT-Kontext gesetzt)
  • :FV — Filter-/Diskriminator-Wert (z.B. TKArt = 170 für E-Mail)
  • Subquery(SELECT [IDST] FROM [STAP] WHERE [IDSTAP] = :FK) holt den denormalisierten Wert direkt aus dem Parent

Hintergrund

Ohne copyColumns schlägt der INSERT mit SQL Server Error 515 fehl („Cannot insert the value NULL into column … column does not allow NULLs“). Das betrifft typischerweise EAV-Tabellen (Entity-Attribute-Value), deren Child-Zeilen sowohl den Parent-FK als auch übergeordnete Gruppen-FKs tragen.

Alle CopyColumn-Bezeichner werden vor der SQL-Interpolation mit QuoteIdent validiert (CWE-89).


Mapping-Quelltypen

Typ SQL-Pattern Beispiel
fsDirect alias.[Col] AS [Field] r.[VN] AS [FirstName]
fsRelated LEFT JOIN / OUTER APPLY mit Diskriminator f1.[B] AS [Email1] WHERE TKArt=170
fsExpression Freies SQL-Fragment (Blacklist-geprüft) CONCAT(r.[VN], ' ', r.[NN]) AS [FullName]

SQL-Test und Debugging

SQL-Test im Mapping-Designer

  1. Öffnen Sie den Mapping-Designer → Schritt Vorschau / SQL-Test.
  2. Das SQL-Memo (oben) zeigt das generierte SELECT-Statement.
  3. Klicken Sie auf Test-Abfrage — bis zu 100 Zeilen werden im Ergebnis-Grid angezeigt.
  4. Bei Fehlern: Kopieren Sie das SQL in SSMS für detaillierte Analyse.

Häufige Probleme

Problem Ursache Lösung
Spalte mehrdeutig Gleicher Spaltenname in mehreren Tabellen Alias-Qualifikation prüfen (r., j0., f1.)
Ergebnis vervielfacht 1:N-Relation ohne singleRow: true singleRow in der Relation aktivieren
Leere Ergebnisse Filter-Wert stimmt nicht filterValue im Feld-Mapping prüfen
SSMA CHECK-Constraint Leere Strings statt NULL Engine setzt automatisch NULL; Spalte prüfen

Sicherheit (CWE-89)

Alle Tabellen- und Spaltennamen aus Mapping-Dateien werden vor der SQL-Interpolation validiert:

  • IsValidIdent — prüft gegen [A-Za-z_][A-Za-z0-9_]*
  • QuoteIdent — klammert in […] für SQL Server
  • Expression-Blacklist — blockiert SELECT, INSERT, DROP, EXEC, xp_ in fsExpression-Feldern
  • Parametrisierung — alle Werte über :P0:Pn Parameter gebunden

→ Details: Sicherheitsarchitektur


Wolfgang van der Stille @ EMSR DATA d.o.o. — Outlook Sync

Zuletzt geändert: den 19.02.2026 um 23:47