Medium severitydata integrity
MySQL Error:
1366
What does this error mean?
MySQL 1366 wordt gegenereerd wanneer de server een waarde probeert in te voegen in een integer-kolom die niet naar een geldig geheel getal kan worden omgezet — typisch een lege string (''), een alfabetische string ('N/A', 'unknown'), of een decimaal getal in een INT-kolom zonder impliciete truncatie. Sinds MySQL 5.7 is STRICT_TRANS_TABLES standaard actief, waardoor dit een harde fout is in plaats van een stille conversie naar 0. In data-pipelines manifesteert dit zich als een plotseling falende pipeline direct na het laadmoment, vaak nadat een bronbestand voor het eerst lege of ontbrekende numerieke waarden bevat.
Common causes
- 1Brondata bevat lege strings ('') in plaats van NULL voor integer-kolommen. CSV-exports van Excel of SFTP-bestanden laten numerieke velden leeg wanneer de waarde ontbreekt, maar MySQL interpreteert '' niet als NULL — in strict mode geeft dit direct error 1366.
- 2Een tekst-string zoals 'N/A', 'unknown', '-', of '#ERROR' staat in een kolom die als INT of BIGINT is gedeclareerd. Dit komt voor wanneer bronschema's geen strikte typing handhaven of wanneer een upstream proces fallback-waarden schrijft als tekst.
- 3ADF column mapping stuurt een bronkolom van type String rechtstreeks naar een MySQL-sinkkolom van type INT, zonder expliciete type-conversie in een Derived Column of Data Flow transformatie. ADF converteert niet automatisch.
- 4Na een MySQL-upgrade van 5.6 naar 5.7 of 8.0 begint een pipeline te falen die daarvoor jarenlang werkte. MySQL 5.6 stond stille truncatie toe; 5.7+ met STRICT_TRANS_TABLES weigert dezelfde waarden.
- 5Een dbt-model doet een INSERT of MERGE vanuit een staging-tabel waar de kolom als VARCHAR is getypeerd, terwijl de doeltabel INT verwacht. CAST ontbreekt in het model omdat de brondata normaal gesproken altijd numeriek was — tot een edge case dit verbreekt.
- 6API-responses retourneren JSON waarbij een numeriek veld soms als string wordt geserialiseerd ('"count": ""') en soms als integer ('"count": 0'), afhankelijk van de API-versie of het endpoint. De pipeline faalt alleen bij de string-variant.
- 7Decimale waarden (bijv. '12.5') worden ingevoegd in een INT-kolom. In non-strict mode wordt dit stilletjes afgerond naar 12; in strict mode genereert dit 1366 omdat de waarde niet exact naar integer converteert zonder informatieverlies.
How to fix it
- 1Stap 1 — Identificeer de probleemkolom via de foutmelding: MySQL 1366 bevat de kolomnaam en de exacte waarde die geweigerd werd, bijv. `Incorrect integer value: '' for column 'order_qty' at row 47`. Gebruik dit om de exacte bron te traceren.
- 2Stap 2 — In ADF Data Flow: voeg een Derived Column transformatie toe vóór de MySQL Sink. Gebruik de expressie `iifNull(toInteger(trim(source_col)), 0)` om lege strings en nulls naar 0 te mappen, of `toInteger(iif(trim(source_col) == '', toString(null()), source_col))` als NULL de gewenste uitkomst is.
- 3Stap 3 — In dbt: cast de kolom expliciet in het model. Gebruik `CAST(NULLIF(TRIM(source_col), '') AS SIGNED) AS int_col` — NULLIF converteert lege strings naar NULL, TRIM verwijdert whitespace-varianten, CAST doet de type-conversie. Voeg een `not_null`-test toe in schema.yml als NULL niet is toegestaan.
- 4Stap 4 — In MySQL direct: gebruik CAST bij de INSERT-statement: `INSERT INTO orders (qty) VALUES (CAST(NULLIF('', '') AS SIGNED));` — dit geeft NULL terug voor lege strings. Als de kolom NOT NULL is, gebruik dan `COALESCE(CAST(NULLIF(val, '') AS SIGNED), 0)`.
- 5Stap 5 — Controleer of strict mode de oorzaak is van een regressie na een upgrade: `SELECT @@GLOBAL.sql_mode;` en `SELECT @@SESSION.sql_mode;`. Als STRICT_TRANS_TABLES aanwezig is en het gedrag vóór de upgrade anders was, overweeg dan of de brondata gecleand moet worden (voorkeur) of dat strict mode projectbreed mag worden aangepast.
- 6Stap 6 — Als tijdelijke workaround voor niet-productiekritieke omgevingen: verwijder STRICT_TRANS_TABLES uit sql_mode via `SET GLOBAL sql_mode = (SELECT REPLACE(@@sql_mode, 'STRICT_TRANS_TABLES', ''));` — dit is een sessie/global instelling en gaat verloren bij herstart. Pas `/etc/mysql/my.cnf` aan voor persistentie. Doe dit alleen als data-kwaliteit niet kritiek is.
- 7Stap 7 — Voeg een data-validatiestap toe aan het begin van de pipeline die rijen met niet-numerieke waarden in integer-kolommen afvangt: `SELECT COUNT(*) FROM staging WHERE source_col REGEXP '[^0-9]' AND source_col != '';`. Log of quarantineer deze rijen in een reject-tabel in plaats van de hele pipeline te laten falen.
Example log output
ErrorCode=UserErrorDataTruncated,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Error happened when loading data into database. SQL Error Code: 1366. Incorrect integer value: '' for column 'order_qty' at row 47.,Source=Microsoft.DataTransfer.ClientLibrary'