Der SQL-Builder (OutlookSync.SqlBuilder.pas) generiert SELECT-, INSERT- und UPDATE-Statements aus der Mapping-Konfiguration.
| 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] |
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
r — Alias für die Wurzeltabelle STAPj0 — LEFT JOIN auf STAdr (1:1-Relation, Index 0)f1 — OUTER 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-BackINSERT 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.
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 )
:FK — Primärschlüssel des Root-Datensatzes (wird vom INSERT-Kontext gesetzt):FV — Filter-/Diskriminator-Wert (z.B. TKArt = 170 für E-Mail)(SELECT [IDST] FROM [STAP] WHERE [IDSTAP] = :FK) holt den denormalisierten Wert direkt aus dem Parent
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).
| 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] |
| 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 |
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 ServerSELECT, INSERT, DROP, EXEC, xp_ in fsExpression-Feldern:P0…:Pn Parameter gebunden→ Details: Sicherheitsarchitektur
Wolfgang van der Stille @ EMSR DATA d.o.o. — Outlook Sync