# Validierungsergebnisse (/docs/de/analytical-apps/pipeline/validation)



Wenn Sie an einem Dataset-Knoten Validierungen konfigurieren - „diese Spalte ist
erforderlich", „diese beiden Spalten müssen zusammen eindeutig sein", „dieser Code
muss in jenem anderen Dataset existieren" -, führt die Plattform sie bei jedem
Pipeline-Lauf aus und veröffentlicht die Ergebnisse als zwei Knoten in Ihrer
Pipeline (sie führt sie außerdem jedes Mal aus, wenn Sie die Daten ansehen - siehe
[weiter unten auf dieser Seite](#im-datenraster)):

| Knoten                | Inhalt                                                                              |
| --------------------- | ----------------------------------------------------------------------------------- |
| **Validation rules**  | Eine Zeile pro konfigurierter Validierung, über alle Dataset-Knoten der App hinweg. |
| **Validation errors** | Eine Zeile pro Dataset-Zeile, die eine Validierung verletzt.                        |

Beide erscheinen auf der Canvas, haben einen Daten-Reiter, können von einem
SQL-Knoten gelesen und von einem Visualisierungs-Widget dargestellt werden. Der
Unterschied ist, dass die Plattform sie schreibt: Sie sind eine eigene Knotenart mit
eigenem Symbol und werden beim Hinzufügen eines Knotens nicht angeboten. Sie öffnen
sich schreibgeschützt und aktualisieren sich selbst, sobald Sie eine Validierung
ändern - es gibt nichts zu pflegen und nichts kaputtzumachen. Beim Öffnen sehen Sie
die von der Plattform geschriebene Abfrage und können sie mit **Ausführen** laufen
lassen, genau wie bei einem SQL-Knoten.

Sie erscheinen in dem Moment, in dem Ihre App ihre erste konfigurierte Validierung
hat, und bleiben danach bestehen. Wenn Sie später jede Validierung entfernen, bleiben
beide Knoten und liefern einfach keine Zeilen mehr, denn Ihre eigenen Abfragen lesen
sie möglicherweise bereits.

## Wie die Knoten heißen [#wie-die-knoten-heißen]

Normalerweise heißen sie `validation_rules` und `validation_errors`, und die Beispiele
auf dieser Seite verwenden diese Namen.

Garantiert sind sie allerdings nicht. Wenn einer Ihrer eigenen Knoten den Namen bereits
hält, nimmt die Plattform den nächsten freien - `validation_rules_2`,
`validation_errors_2` und so weiter -, statt Ihren Knoten anzutasten. Ihr vorhandener
Knoten behält Namen und Inhalt; das erzeugte Paar steht einfach daneben. Wenn Sie eine
Abfrage gegen diese Knoten schreiben, prüfen Sie den Namen zuerst auf der Canvas und
verwenden Sie den, den Ihre App tatsächlich hat.

## Validation errors [#validation-errors]

| Spalte                 | Bedeutung                                                                    |
| ---------------------- | ---------------------------------------------------------------------------- |
| `dataset_technical_id` | Der Dataset-Knoten, zu dem die fehlerhafte Zeile gehört.                     |
| `row_id`               | Die stabile ID dieser Zeile.                                                 |
| `column_technical_id`  | Die Spalte, bei einer Regel pro Spalte. Leer bei einer Bedingungsbaum-Regel. |
| `rule_id`              | Verbindet mit `validation_rules.rule_id`.                                    |
| `check_type`           | Die Prüfung, die fehlgeschlagen ist.                                         |
| `validation_error`     | Die Meldung, die den Fehler beschreibt.                                      |

`row_id` ist der eigentliche Zweck der Tabelle. Es ist dieselbe stabile Zeilen-ID,
die auch das Datenraster verwendet, und die Tabelle jedes Dataset-Knotens führt sie als
`_row_id` (siehe [SQL-Knoten](./sql-nodes.mdx#die-zeilen-id-eines-datasets-lesen)),
sodass Sie einen Befund mit der zugehörigen Zeile verbinden können - mit dem Namen, den
Ihre App dem Knoten tatsächlich gegeben hat, falls es nicht der übliche ist:

```sql title="orders_with_findings.sql"
SELECT o.*, e.validation_error
  FROM orders o
  LEFT JOIN validation_errors e
    ON e.dataset_technical_id = 'orders'
   AND e.row_id = o._row_id
```

Eine Zeile ohne passenden Befund ist eine vertrauenswürdige Zeile. Eine Zeile mit
mehreren verletzten Regeln erscheint einmal pro Regel, sodass eine Zeile mit zwei
Verstößen zwei Zeilen ergibt, unterschieden durch `rule_id`.

### Einen SQL-Knoten auf die Befunde stützen [#einen-sql-knoten-auf-die-befunde-stützen]

Am nützlichsten bauen Sie daraus einen Knoten, der nur die Zeilen führt, zu denen es
keinen Befund gibt - alles Nachgelagerte arbeitet dann auf bereits geprüften Daten:

```sql title="trusted_orders.sql"
SELECT o.*
  FROM orders o
 WHERE NOT EXISTS (
   SELECT 1 FROM validation_errors e
    WHERE e.dataset_technical_id = 'orders'
      AND e.row_id = o._row_id
 )
```

**Deklarieren Sie `validation_errors` als Eingabetabelle**, neben dem Dataset:

```yaml
input_tables:
  - orders
  - validation_errors
```

Die Validierungsknoten laufen immer zuerst, vor jedem Knoten, den Sie selbst schreiben.
Eine Abfrage, die sie liest, sieht also stets die Befunde desselben Laufs - unabhängig
davon, ob Sie sie deklarieren. Die Deklaration bringt den Pfeil auf der Arbeitsfläche:
ohne sie liefert der Knoten weiterhin das richtige Ergebnis, aber im Diagramm ist nicht
zu sehen, dass er von den Validierungsergebnissen abhängt - und wer Ihre Pipeline als
Nächstes liest, erkennt den Zusammenhang nicht.

Um auf eine bestimmte Prüfung statt auf jeden Befund zu stützen, ergänzen Sie
`AND e.check_type = 'required'` (oder verbinden Sie `validation_rules` und filtern dort).

## Im Datenraster [#im-datenraster]

Sie müssen den Knoten nicht abfragen, um zu sehen, was fehlgeschlagen ist. Öffnen Sie
den Tab **Daten** eines Dataset-Knotens: Dort sind die fehlerhaften Zellen markiert,
mit der Begründung beim Überfahren mit der Maus - eine kräftige Markierung auf der
Zelle, die eine Regel pro Spalte benannt hat, eine schwächere über allen Zellen einer
Zeile, die ein Bedingungsbaum zurückgewiesen hat. Beim Überfahren einer markierten
Zelle erscheint die Begründung und nur sie - der übliche Hinweis, der den Zellinhalt
wiederholt, tritt dafür zurück.

**Die Markierungen kommen zusammen mit den Zeilen.** Das Raster fordert eine Seite mit
Daten an und erhält in derselben Antwort die Befunde zu genau diesen Zeilen - geprüft an
den Zeilen, die es Ihnen gleich zeigt. Es gibt keinen Lauf zu nennen und kein
„geprüft am" zu berücksichtigen, denn Zeilen und Markierungen stammen aus ein und
derselben Leseoperation. Daraus folgt:

* **Nichts ist veraltet, und nichts wird entfernt.** Speichern Sie eine Änderung im
  Raster oder schließen Sie einen Import ab, werden die betroffenen Zeilen beim nächsten
  Lesen erneut geprüft: Eine behobene Markierung ist weg, eine soeben verletzte Regel
  erscheint, und alle anderen Zeilen behalten ihre eigenen Markierungen. Sie müssen dafür
  die Pipeline nicht ausführen.
* **Eine Zeile, die jemand anderes hinzugefügt oder geändert hat**, wird beim nächsten
  Lesen genauso geprüft.
* **Jede fehlerhafte Zeile vor Ihnen ist markiert**, bei jeder Datasetgröße. Die Befunde
  einer Zeile reisen mit der Zeile, ein Block ist also markiert, sobald er erscheint - es
  gibt keinen festen ersten Ausschnitt, keinen halb markierten Bildschirm und nichts, was
  verspätet nachkommt.
* **Die Zeile über dem Raster beschreibt das ganze Dataset**, nicht die Seite: entweder
  keine Befunde oder wie viele Zeilen etwas verletzen. Diese Anzahl ändert sich nicht,
  wenn Sie blättern, suchen oder filtern.

Neben der Anzahl steht **Nur fehlerhafte Zeilen anzeigen**: Damit schränken Sie das
Raster auf die Zeilen ein, die mindestens eine Prüfung verletzen - und wieder zurück.

Ein Dataset ohne eigene Validierungen zeigt gar keine Zeile, auch wenn andere Datasets
derselben App viele haben.

**Auch die Datenansicht eines Laufs und die einer Version sind markiert**, jeweils mit
ihrer eigenen Antwort. Ein Lauf zeigt genau das, was dieser Lauf gefunden hat. Eine
Version wird mit den Validierungen geprüft, wie sie bei ihrer Veröffentlichung
konfiguriert waren, und mit den Daten von damals - eine historische Ansicht wird also nie
nach den heutigen Regeln neu beurteilt.

Wenn die Prüfungen überhaupt nicht laufen können - etwa weil die Plattform eine der
Tabellen, die eine Regel liest, nicht auflösen kann -, sagt die Zeile, dass die
Validierungen nicht geprüft werden konnten, und es wird nichts markiert. **Ihre Daten
sind davon nicht betroffen**: Jede Zeile ist da, in der richtigen Reihenfolge, mit der
richtigen Gesamtzahl. Eine fehlgeschlagene Validierung kostet Sie die Markierungen, nie
die Daten.

## Auf einer Visualisierungsseite [#auf-einer-visualisierungsseite]

Dieselben Markierungen erscheinen in einem **Tabellen-Widget**, das auf einem Dataset
beruht. So sehen die Personen, die die App lesen statt sie zu bauen, was die Validierung
gefunden hat, ohne die Pipeline zu öffnen. Die Begründung erscheint auch dort beim
Überfahren mit der Maus, und die Markierungen sind an genau den Zeilen geprüft, die die
Tabelle zeigt.

Drei Unterschiede zum Tab **Daten**, alle bewusst:

* **Die Zeile über der Tabelle erscheint nur, wenn es etwas zu warnen gibt**: dass
  Befunde vorliegen oder dass die Prüfungen nicht laufen konnten. Ein sauberes Dataset
  wird einfach ohne Streifen gezeigt, damit aus einer Seite voller Tabellen keine Seite
  voller Hinweise wird.
* **Eine gruppierte oder zusammengefasste Tabelle wird nicht markiert.** Ihre Zeilen sind
  Summen über viele Ursprungszeilen, nicht die Zeilen, die eine Regel benannt hat. Ebenso
  wenig eine Tabelle über einer SQL-Transformation: Ein Befund gehört zu einer
  Dataset-Zeile, und die Ausgabezeilen einer Transformation sind keine Dataset-Zeilen.
* **Es gibt kein „Nur fehlerhafte Zeilen anzeigen".** Das ist ein Werkzeug der
  Autorinnen und Autoren und bleibt im Tab **Daten**; eine Seite gestaltet, wer sie
  gebaut hat.

### Solange ein Entwurf offen ist, wird die veröffentlichte App so geprüft, wie sie veröffentlicht wurde [#markierungen-und-entwuerfe]

Ein offener Entwurf lässt jede Dataset-Tabelle der veröffentlichten App die
**veröffentlichte Momentaufnahme** der Daten lesen statt der aktuellen Zeilen, damit eine
halbfertige Änderung von Ihnen nicht zu den Lesenden durchsickert (siehe
[Entwurf und Veröffentlichung](../../overview/apps.mdx#entwurf-und-veroeffentlichung)).
Die Markierungen folgen dem genau: Die Tabelle wird mit den Validierungen der Version
geprüft, die sie zeigt, und über der Momentaufnahme, die sie zeigt. Ihr Team sieht also,
was die veröffentlichte App über die veröffentlichten Daten sagt, während der Tab
**Daten** im Editor weiterhin die aktuellen Zeilen gegen die Regeln prüft, die Sie gerade
bearbeiten. Keine der beiden Ansichten übernimmt die Antwort der anderen, und keine muss
auf einen Lauf warten.

## Validation rules [#validation-rules]

| Spalte                 | Bedeutung                                                                                                                                                                                                                                                                              |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rule_id`              | Die Identität der Regel innerhalb dieses Laufs - `col:<dataset>.<spalte>.<n>` bei einer Regel pro Spalte, wobei `n` ihre Position in der Prüfungsliste dieser Spalte ist, und `tree:<dataset>.<n>` bei einem Bedingungsbaum, wobei `n` ihre Position in der Liste dieses Datasets ist. |
| `dataset_technical_id` | Der Dataset-Knoten, an dem die Regel konfiguriert ist.                                                                                                                                                                                                                                 |
| `column_technical_id`  | Die Spalte, bei einer Regel pro Spalte. Leer bei einer Bedingungsbaum-Regel.                                                                                                                                                                                                           |
| `rule_kind`            | `column`, `complex` oder `overflow`.                                                                                                                                                                                                                                                   |
| `check_type`           | Der Operator bei einer Regel pro Spalte, oder die oberste Gruppe eines Bedingungsbaums.                                                                                                                                                                                                |
| `parameter`            | Der Wert, gegen den geprüft wird, sofern die Prüfung einen benötigt.                                                                                                                                                                                                                   |
| `error_message`        | Die Meldung, die die Regel bei Verletzung ausgibt.                                                                                                                                                                                                                                     |
| `compilable`           | Ob die Regel tatsächlich ausgeführt wird.                                                                                                                                                                                                                                              |
| `skip_reason`          | Leer, wenn die Regel läuft, sonst der Grund, warum nicht.                                                                                                                                                                                                                              |

Diese Tabelle ist keine Dekoration: **Validation errors** liest `check_type` und
`error_message` aus ihr. Wenn Sie also die Meldung einer Bedingungsbaum-Regel ändern,
ändert sich damit, was Ihre Befunde sagen, ohne dass sich sonst etwas ändert.

## Was die einzelnen Prüfungen bedeuten [#was-die-einzelnen-prüfungen-bedeuten]

Für alle Prüfungen gilt eine gemeinsame Regel, die vor der Tabelle zu lesen ist:

> **Ein leerer Wert besteht jede Prüfung außer `Pflichtfeld`.**

Ein leerer Wert ist eine leere Zelle oder eine, die nur Leerzeichen enthält. Ohne
diese Regel würde eine optionale Spalte mit einer Musterprüfung jede leere Zelle als
Fehler melden, was nicht bedeutet, was „optional" bedeutet. Wenn leere Werte für eine
Spalte wichtig sind, fügen Sie `Pflichtfeld` neben der anderen Prüfung hinzu.

| Prüfung                                                  | Verletzt, wenn                                                                                                                                        |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| Pflichtfeld                                              | Die Zelle leer ist. Was „leer" je Spaltentyp bedeutet, steht in der Tabelle weiter unten. Dies ist die einzige Prüfung, die ein leerer Wert verletzt. |
| Eindeutig                                                | Eine andere Zeile denselben Wert hält. Jede Kopie eines Duplikats wird gemeldet, nicht nur die späteren. Leere Zellen sind nie Duplikate voneinander. |
| Gleich                                                   | Der Wert nicht gleich dem angegebenen ist.                                                                                                            |
| Größer als                                               | Der Wert nicht größer als der angegebene ist.                                                                                                         |
| Kleiner als                                              | Der Wert nicht kleiner als der angegebene ist.                                                                                                        |
| Größer gleich                                            | Der Wert unter dem angegebenen liegt.                                                                                                                 |
| Kleiner gleich                                           | Der Wert über dem angegebenen liegt.                                                                                                                  |
| Entspricht Muster (`like`)                               | Der Text dem Muster nicht entspricht. `%` steht für eine beliebige Zeichenfolge, `_` für ein Zeichen.                                                 |
| Entspricht Muster (Groß-/Kleinschreibung egal) (`ilike`) | Dasselbe, ohne Beachtung von Groß- und Kleinschreibung.                                                                                               |
| Beginnt mit                                              | Der Text nicht mit dem angegebenen Wert beginnt.                                                                                                      |
| Endet mit                                                | Der Text nicht mit dem angegebenen Wert endet.                                                                                                        |
| Entspricht Ausdruck (`regex`)                            | Der Text dem regulären Ausdruck nicht entspricht.                                                                                                     |

Zwei Folgerungen ergeben sich daraus, beide beabsichtigt:

* **Ein Wert, der sich nicht vergleichen lässt, verletzt einen Vergleich.** Trägt eine
  Spalte mit dem Wert `abc` die Prüfung „größer als 0", wird diese Zeile gemeldet. Der
  Wert lässt sich nicht vergleichen, und ein nicht vergleichbarer Wert ist nicht
  größer als null.
* **Eine Prüfung, deren Antwort unbekannt ist, zählt als Verletzung.** Die Plattform
  liest „unbekannt" nie als „in Ordnung".

### Welche Prüfungen eine Spalte anbietet [#welche-prüfungen-eine-spalte-anbietet]

Welche Prüfungen eine Spalte anbietet, folgt daraus, was diese Spalte enthält - ein
Datum wird also mit einem Datum verglichen und ein Ja/Nein mit einem Ja/Nein:

| Spaltentyp      | Pflichtfeld | Eindeutig | Gleich | Größer / kleiner | Die fünf Textmuster |
| --------------- | ----------- | --------- | ------ | ---------------- | ------------------- |
| Text            | ja          | ja        | nein   | nein             | ja                  |
| Langtext        | ja          | ja        | nein   | nein             | ja                  |
| Telefon         | ja          | ja        | nein   | nein             | ja                  |
| E-Mail          | ja          | ja        | nein   | nein             | ja                  |
| Ganzzahl        | ja          | ja        | ja     | ja               | nein                |
| Dezimalzahl     | ja          | ja        | ja     | ja               | nein                |
| Prozent         | ja          | ja        | ja     | ja               | nein                |
| Währung         | ja          | ja        | ja     | ja               | nein                |
| Jahr            | ja          | ja        | ja     | ja               | nein                |
| Datum           | ja          | ja        | ja     | ja               | nein                |
| Uhrzeit         | ja          | ja        | ja     | ja               | nein                |
| Zeitstempel     | ja          | ja        | ja     | ja               | nein                |
| Boolean         | ja          | nein      | ja     | nein             | nein                |
| Dropdown        | ja          | ja        | ja     | nein             | nein                |
| Mehrfachauswahl | ja          | nein      | nein   | nein             | nein                |
| Anhang          | ja          | nein      | nein   | nein             | nein                |

Die Regel hinter der Tabelle: **Pflichtfeld** wird überall angeboten; **Eindeutig**
überall dort, wo eine Zelle einen Wert hält, der eine Zeile identifizieren könnte (also
nicht bei Boolean mit seinen zwei Werten, nicht bei Mehrfachauswahl und nicht bei
Anhang); **Gleich** überall dort, wo es einen exakten Vergleichswert gibt; die geordneten
Vergleiche überall dort, wo Werte eine Ordnung haben; und die fünf Textmuster bei den
vier freien Texttypen. Bei einer Textspalte IST **Entspricht Muster** ohne `%` bereits
ein exakter Vergleich - deshalb wird Gleich dort nicht als zweite Schreibweise derselben
Prüfung angeboten.

**Eine früher konfigurierte Prüfung wird nie entfernt.** Wenn Sie den Typ einer Spalte
nach dem Konfigurieren ihrer Prüfungen ändern, bleiben die Prüfungen, laufen weiter und
werden weiterhin im Editor angezeigt - sie werden lediglich nicht mehr zum Hinzufügen
angeboten.

### Was als Wert einzutragen ist [#was-als-wert-einzutragen-ist]

Der Vergleichswert muss ein Wert sein, den die Spalte selbst halten könnte:

| Spaltentyp                              | Das eintragen                 | Beispiel              |
| --------------------------------------- | ----------------------------- | --------------------- |
| Ganzzahl, Dezimalzahl, Prozent, Währung | eine Zahl                     | `1500`, `-3.5`        |
| Jahr                                    | vier Ziffern                  | `2026`                |
| Datum                                   | `YYYY-MM-DD`                  | `2026-01-01`          |
| Uhrzeit                                 | `HH:mm` oder `HH:mm:ss`       | `12:30`               |
| Zeitstempel                             | `YYYY-MM-DDTHH:mm:ss`         | `2026-01-01T08:00:00` |
| Boolean                                 | aus den zwei Optionen gewählt | `Wahr`                |
| Dropdown                                | der exakte Text der Option    | `EU`                  |
| Text, Langtext, Telefon, E-Mail         | beliebiger Text (das Muster)  | `A%`                  |

Ein Wert außerhalb dieses Formats führt dazu, dass die Regel **übersprungen** statt
geraten wird: Sie erscheint in **Validation rules** mit `compilable` false und
`skip_reason` `operand_type_mismatch`, und alle anderen Regeln laufen weiter. Der Editor
markiert das Feld schon beim Tippen, Sie sehen es also in der Regel vor dem Speichern.

Zwei Details, die man kennen sollte:

* Der Wert wird normalisiert gespeichert, und genau das meldet **Validation rules** in
  `parameter` zurück: `12:30` wird zu `12:30:00`, `2026-01-01T08:00:00` wird zu
  `2026-01-01 08:00:00`, und `JA` wird zu `true`.
* Dezimalzahl, Prozent und Währung werden als Gleitkommazahlen verglichen. Ein Wert mit
  mehr Präzision, als sich damit darstellen lässt, ist möglicherweise nicht exakt gleich -
  **Gleich** auf einer Geldspalte ist deshalb nur für runde Beträge zu empfehlen.

### Was „Pflichtfeld" je Spaltentyp bedeutet [#was-pflichtfeld-je-spaltentyp-bedeutet]

Pflichtfeld ist eine einzige Prüfung - „die Zelle ist nicht leer" - und was leer
bedeutet, folgt daraus, was die Spalte speichert:

| Spaltentyp      | Pflichtfeld ist verletzt, wenn                                                                                                                                                                                   |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Mehrfachauswahl | Keine Option ausgewählt ist. Eine Mehrfachauswahl-Zelle speichert ihre Optionen als einen Text, ohne Auswahl also gar nichts - „mindestens eine Option ausgewählt" ist hier genau die Bedeutung von Pflichtfeld. |
| Boolean         | Die Zelle leer ist. `false` ist ein WERT und ist erfüllt: Um das Häkchen zu erzwingen, nutzen Sie **Gleich** `Wahr`.                                                                                             |
| Anhang          | Die Zelle keinen Anhang enthält.                                                                                                                                                                                 |
| Dropdown        | Keine Option gewählt ist.                                                                                                                                                                                        |
| Alles andere    | Die Zelle leer ist oder nur Leerzeichen enthält.                                                                                                                                                                 |

Eine Zelle, die in einer Anhang-Spalte den Text `[]` enthält, gilt NICHT als leer. Die
Leer-Regel ist eine Regel für jeden Spaltentyp, und eine eigene für Anhänge wäre eine
zweite Regel, die man mit ihr im Gleichklang halten müsste.

### Bedingungsbäume [#bedingungsbäume]

Eine komplexe Validierung kombiniert Prüfungen zu einem Baum; die Gruppen bedeuten:

| Gruppe    | Verletzt, wenn                                                                                                                                                                       |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| AND       | Eine der untergeordneten Prüfungen verletzt ist.                                                                                                                                     |
| OR        | Jede untergeordnete Prüfung verletzt ist.                                                                                                                                            |
| NOT       | Die untergeordnete Prüfung erfüllt ist.                                                                                                                                              |
| UNIQUE    | Eine andere Zeile dieselbe Kombination der aufgeführten Spalten hält. Eine Zeile, in der IRGENDEINE dieser Spalten leer ist, ist ausgenommen - ein Teilschlüssel ist kein Schlüssel. |
| REFERENCE | Der Wert der Zeile in der Spalte des Ziel-Datasets nicht existiert. Ein leerer Quellwert ist ausgenommen. Der Vergleich ignoriert umgebende Leerzeichen, `" 1"` passt also zu `"1"`. |

Eine Prüfung innerhalb eines Baums verhält sich genau wie die Variante pro Spalte,
einschließlich der Leer-Regel - mit einer Folge, die man kennen sollte:

> `NOT (Spalte entspricht "x%")` **wird bei einer leeren Spalte verletzt**, weil die
> innere Prüfung bei einem leeren Wert erfüllt ist und `NOT` sie umkehrt.

Wenn das nicht gewünscht ist, setzen Sie die Prüfung in ein `AND` neben
`Pflichtfeld`.

## Wenn eine Regel nicht laufen kann [#wenn-eine-regel-nicht-laufen-kann]

Eine Regel, die die Plattform nicht in eine korrekte Prüfung übersetzen kann, wird nie
als fehlerhafte Prüfung ausgeführt. Sie wird übersprungen, und das Überspringen ist
sichtbar: Die Regel bleibt eine Zeile in **Validation rules**, mit `compilable` false
und einem `skip_reason`. Alle anderen Regeln laufen weiter, und der Pipeline-Lauf
selbst ist nicht betroffen.

Finden Sie sie mit einem SQL-Knoten, einem Visualisierungs-Widget oder einer
Ad-hoc-Abfrage:

```sql title="skipped_rules.sql"
SELECT rule_id, dataset_technical_id, column_technical_id, check_type, skip_reason
  FROM validation_rules
 WHERE NOT compilable
```

| `skip_reason`                  | Was zu tun ist                                                                                                                                                                                                                                       |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `operand_missing`              | Die Prüfung braucht einen Vergleichswert, es wurde keiner angegeben. Tragen Sie ihn nach.                                                                                                                                                            |
| `operand_not_numeric`          | Eine Prüfung auf einer Zahlenspalte erhielt etwas, das keine Zahl ist. Korrigieren Sie den Wert.                                                                                                                                                     |
| `operand_type_mismatch`        | Der Wert ist keiner, den der Typ der Spalte halten könnte - ein Datum, das nicht `YYYY-MM-DD` ist, ein Jahr ohne vier Ziffern, eine Uhrzeit außerhalb von 24 Stunden, ein Ja/Nein, das keines ist. Siehe „Was als Wert einzutragen ist" weiter oben. |
| `column_not_found`             | Die Regel nennt eine Spalte, die das Dataset nicht mehr hat. Richten Sie sie auf eine vorhandene Spalte aus oder entfernen Sie sie.                                                                                                                  |
| `reference_target_not_found`   | Das Dataset, auf das die Referenz zeigt, existiert nicht mehr.                                                                                                                                                                                       |
| `reference_target_not_dataset` | Eine Referenz muss auf einen Dataset-Knoten zeigen, nicht auf einen SQL-Knoten oder einen Import.                                                                                                                                                    |
| `reference_column_not_found`   | Die Referenz nennt eine Spalte, die das Ziel-Dataset nicht hat.                                                                                                                                                                                      |
| `tree_incomplete`              | Eine Gruppe hat keine Kinder, ein `NOT` hat mehr als eines, ein `UNIQUE` führt keine Spalten auf, oder ein `REFERENCE` bildet keine Spalten ab. Vervollständigen Sie die Regel.                                                                      |
| `rule_budget_exceeded`         | Siehe unten.                                                                                                                                                                                                                                         |

### Die Overflow-Zeile [#die-overflow-zeile]

Es gibt eine Obergrenze dafür, wie viele Validierungen die erzeugten Knoten einer App
abbilden können. Eine App, die sie überschreitet, erhält in **Validation rules** eine
zusätzliche Zeile mit der `rule_id` `overflow`, deren `parameter` angibt, wie viele
konfigurierte Validierungen nicht abgebildet sind, und deren Meldung das erklärt. Die
nicht abgebildeten Validierungen fehlen schlicht; Ihr Dataset wird trotzdem normal
gespeichert.

Wenn Sie das sehen, besteht die Lösung darin, weniger und aussagekräftigere
Validierungen zu führen - oder die Datasets auf mehrere Apps aufzuteilen.

## Was dies nicht tut [#was-dies-nicht-tut]

* **Eine verletzte Validierung blockiert nie einen Schreibvorgang.** Validierung ist
  beobachtend: Ein Lauf meldet, was nicht stimmt, er weist Ihre Daten nie zurück. Sie
  entscheiden, was zu tun ist.
* **Es gibt keine Warnstufe.** Jede konfigurierte Validierung ist ein Fehler, wenn sie
  verletzt wird.
* **Die gespeicherten Meldungen sind auf Englisch.** Sie gehören zu einer gemeinsamen
  Tabelle, die im Moment ihrer Erstellung keine Lesersprache kennt. Die strukturierten
  Spalten daneben (`check_type`, `parameter`, `column_technical_id`) sind das, woraus
  eine übersetzte Ansicht rendert - und genau das tut das Datenraster: Seine
  Zellbegründungen sind für jede Prüfung pro Spalte in Ihrer Sprache und bei einem
  Bedingungsbaum die Meldung, die Sie selbst geschrieben haben.
