Eine schrittweise Anleitung für die Migration einer bestehenden gespeicherten Prozedur zu Databricks. Cursor, temporäre Tabellen und Multi-Statement-Transaktionen werden im Rahmen der Data-Warehouse-Migration alle als SQL übertragen.
von Abhishek Dey und Laurent Léturgez
Irgendwo in Ihrem Data Warehouse erwachen jede Nacht Hunderte von gespeicherten Prozeduren und halten still und leise den Betrieb am Laufen. Sie wurden vor Jahren von einer Gruppe von SQL-Entwicklern geschrieben, die das Unternehmen längst verlassen haben. Sie enthalten verschachtelte Cursor. Sie erstellen spontan temporäre Tabellen. Sie bündeln Aktualisierungen über mehrere Tabellen hinweg in einer einzigen Transaktion. Und irgendwo um Zeile 47 herum gibt es einen Kommentar, der einfach lautet: „Nichts hieran ändern.“ Niemand versteht diese Prozeduren mehr so richtig. Dennoch hängt jeder von ihnen ab. Das Umsatz-Dashboard, der Finanzabschluss, der Betriebsbericht – sie alle lassen sich auf die eine oder andere Weise auf diese Ebenen der prozeduralen SQL-Geschäftslogik zurückführen.
Das Verschieben von Daten in das Lakehouse ist ein bewährter Prozess. Die Hürde lag bisher im prozeduralen Kern jeder Data-Warehouse-Migration: den gespeicherten Prozeduren, der Transaktionsverarbeitung, den temporären Tabellen, dem Kontrollfluss und der Tatsache, dass ein Großteil des Unternehmens nach wie vor auf SQL-Kenntnissen basiert. Jedes Mal, wenn eine Migration anstand, waren diese Prozeduren das Erste, worauf alle zeigten: „Wir können nicht migrieren, solange wir das nicht mit minimalen Änderungen ausführen können. Unser Unternehmen ist immer noch stark SQL-gesteuert.“
Deshalb haben wir uns entschieden, einen Anwendungsfall wie den, an den Sie wahrscheinlich gerade denken – eine zusammengesetzte Prozedur, die uns bei Migrationen immer wieder begegnet –, Schritt für Schritt auf dem Lakehouse zu demonstrieren. Dieses Beispiel basiert auf einem Oracle-Migrationsszenario, kann aber auf jedes beliebige Data Warehouse (ob Legacy oder Cloud-basiert) angewendet werden.
Diese Beispielprozedur verarbeitet tägliche Bestellungen. Sie stellt nicht verarbeitete Bestellungen in einer temporären Tabelle bereit, gleicht sie mit den Kundenstammdaten ab, durchläuft Fehler in einer Schleife, um jede Ablehnung einzeln zu protokollieren, aktualisiert dann die regionalen Umsatzübersichten und markiert alle Bestellungen als verarbeitet – und das alles innerhalb einer Transaktion, die bei einem Fehler zurückgesetzt wird.
Ein nächtlicher Job, der keinesfalls ausfallen darf.
Früher bedeutete die Migration eine komplette Neuschreibung in Python und Spark. Wochenlange Arbeit, neue Fehler, die es zu finden galt, und ein SQL-Team, das seine eigene Geschäftslogik nicht mehr pflegen konnte.
Wir haben sie nicht neu geschrieben. Wir haben sie übersetzt.
Jede Prozedur beginnt mit einer Signatur und einem Sicherheitsnetz. Das Altsystem verpackte den Rumpf in BEGIN ... EXCEPTION ... END. Databricks verwendet stattdessen DECLARE EXIT HANDLER FOR SQLEXCEPTION ; gleiche Idee, leicht andere Syntax. Nehmen wir an, dass der entsprechende Katalog und das Schema in der Sitzung festgelegt wurden.
Der große Unterschied liegt nicht im Code. Sondern in dem, was nach der Bereitstellung geschieht. Auf Databricks wird die Prozedur in Unity Catalog registriert. Sie erhält Zugriffskontrollen, Lineage auf Spaltenebene und ist über jeden Workspace hinweg auffindbar. Im aktuellen System befand sie sich in einem Schema, für das gerade einmal drei Personen das Passwort hatten.
Legacy | Databricks |
CREATE OR REPLACE PROCEDURE name IS | CREATE OR REPLACE PROCEDURE [IF NOT EXISTS] <catalog>.<schema>.<procedure_name> ( [ procedure_parameter [, ...] ] ) [ characteristic [...] ] LANGUAGE SQL SQL SECURITY { INVOKER | DEFINER } AS BEGIN |
v_id NUMBER; vor BEGIN | DECLARE v_id INT; innerhalb von BEGIN |
EXCEPTION WHEN OTHERS THEN | DECLARE EXIT HANDLER FOR SQLEXCEPTION |
Referenz: docs.databricks.com/aws/en/sql/language-manual/sql-ref-syntax-ddl-create-procedure
Die ursprüngliche Prozedur erstellt zwei temporäre Tabellen für Staging- und Validierungsfehler. Sie dienen als Zwischenspeicher, von dem die restliche Logik abhängt.
Auf Databricks wird dies zu einem der einfachsten Teile der Migration. Kein EXECUTE IMMEDIATE. Kein ON COMMIT PRESERVE ROWS. Die auf die Sitzung beschränkte CREATE TEMP TABLE ist der direkte Ersatz mit einer kleinen Einschränkung: CREATE OR REPLACE TEMP TABLE wird noch nicht unterstützt. Führen Sie also zuerst einen Drop durch, wenn Sie in derselben Sitzung erneut ausführbar sein müssen.
Referenz: docs.databricks.com/aws/en/tables/temporary-tables
Das war der Teil, von dem alle annahmen, dass er neu geschrieben werden müsste. Die ursprüngliche Prozedur durchläuft die Validierungsfehler nacheinander, lehnt jede fehlerhafte Bestellung ab und protokolliert den Grund. Ein klassisches Cursor-Muster. Jahrzehnte altes, vererbtes (z. B. Oracle) Muskelgedächtnis.
Das SQL-Scripting von Databricks unterstützt Cursor nativ, OPEN, FETCH und CLOSE seit Runtime 18.1. Das %NOTFOUND -Attribut wird zu einem CONTINUE HANDLER FOR NOT FOUND. Schleifen-Labels und LEAVE ersetzen EXIT WHEN.
Die bedingte Prüfung – wenn keine Zeilen zu verarbeiten sind, überspringen und protokollieren – hat sich kaum geändert. SELECT ... INTO wird zu SET var = (SELECT ...). Alles andere ist identisch.
Unser SQL-Scripting unterstützt das gesamte prozedurale Toolkit: IF/ELSE, WHILE, FOR, LOOP, REPEAT, LEAVE, ITERATE, SIGNAL/RESIGNAL. Wenn Ihre Codebasis Teradata-BTEQ-Skripte mit .GOTO und .LABEL -Anweisungen enthält, lassen sich diese mit LEAVE und ITERATE auf benannte Schleifen abbilden.
Referenz: docs.databricks.com/aws/en/sql/language-manual/sql-ref-scripting
Das war das letzte Puzzleteil, das die Migration überhaupt erst machbar gemacht hat. Die ursprüngliche Prozedur aktualisiert regional_revenue, markiert Bestellungen als verarbeitet und protokolliert den Batch. Wenn ein Teil fehlschlägt, wird alles zurückgesetzt (Rollback).
Auf dem Altsystem ist dies eine implizite Transaktion mit einem expliziten COMMIT. Auf Databricks bietet BEGIN ATOMIC ... END dieselbe Semantik – automatisches Commit bei Erfolg, automatisches Rollback bei Fehler – mit einem entscheidenden Vorteil: Konflikterkennung auf Zeilenebene. Gleichzeitige Batches, die in dieselbe Tabelle schreiben, stehen nur dann in Konflikt, wenn sie dieselben Zeilen betreffen. Beispielsweise verwenden sowohl Oracle als auch Snowflake Sperren auf Tabellenebene, was eine serielle Ausführung erzwingt.
Die MERGE-Anweisung kann unverändert zu Databricks migriert werden. Das explizite COMMIT ist weggefallen, da BEGIN ATOMIC dies übernimmt. Und das Team musste sich keine Sorgen mehr machen, dass sich gleichzeitige Batch-Jobs gegenseitig in die Quere kommen.
Zwei praktische Hinweise, wenn Sie dieses Muster übernehmen:
Referenz: docs.databricks.com/aws/en/transactions/
Gleiche Geschäftslogik. Gleicher Kontrollfluss. Verwaltet durch Unity Catalog.
Um es innerhalb einer Transaktion auszuführen, kapseln Sie den Aufruf:
Die Migrationszeitpläne für diese Programme können um 50–75 % verkürzt werden, selbst bei komplexen Stored Procedures mit starken PL/SQL-Paketabhängigkeiten. Diese Effizienz resultiert aus einem mechanischen Übersetzungsprozess, der die ursprüngliche Geschäftslogik beibehält und sicherstellt, dass das SQL-Team seine Wartungsarbeiten nahtlos fortsetzen kann. Über die Migration selbst hinaus gewinnen Teams einen starken neuen Vorteil: eine einheitliche Plattform, auf der dieselben kontrollierten Daten ihre Dashboards, Machine-Learning-Modelle und KI-Initiativen speisen.
Der einzige Weg, um herauszufinden, ob Ihre Prozeduren übersetzt werden können, ist, es auszuprobieren. Wählen Sie die kleinste Stored Procedure in Ihrem Batch aus, vorzugsweise eine, die niemand gerne debuggt. Erstellen Sie ein Migrationsprojekt in Ihrem Workspace und legen Sie mit dem Agentic Code Convertor los!
(Dieser Blogbeitrag wurde mit KI-gestützten Tools übersetzt.) Originalbeitrag
Abonnieren Sie unseren Blog und erhalten Sie die neuesten Beiträge direkt in Ihren Posteingang.