SAP-B1-Abfragen von SQL Server nach HANA migrieren

Von Zain Abbas, Kodenova · Aktualisiert am

Kurz gesagtHANA arbeitet mit SQL im ANSI-Stil. Die meisten SAP-Business-One-Abfragen brauchen deshalb kleine, aber strikte Anpassungen: Spaltennamen in Anführungszeichen setzen (T0."CardCode"), ISNULL durch IFNULL ersetzen, GETDATE durch CURRENT_TIMESTAMP, DATEADD und DATEDIFF durch ADD_DAYS und DAYS_BETWEEN, CONVERT durch TO_NVARCHAR und + durch || beim Verketten von Zeichenketten. Einfache Abfragen sind in wenigen Minuten umgestellt. Stored Procedures, temporäre Tabellen und SBO_SP_TransactionNotification müssen in SQLScript neu geschrieben und mit denselben Daten getestet werden.

Warum Ihre Abfragen auf HANA nicht mehr laufen

Wenn ein Unternehmen SAP Business One von Microsoft SQL Server auf SAP HANA umstellt, werden die Daten sauber übernommen. Das eigene SQL nicht. Gespeicherte Abfragen, Alarme, formatierte Suchen, Commands in Crystal Reports, das SQL von Add-ons und die Transaction Notification enthalten durchweg T-SQL. Und HANA versteht kein T-SQL.

Die meisten Änderungen sind klein. Das Problem ist ihre Menge, und ein einziges vergessenes Anführungszeichen legt die ganze Abfrage lahm. In diesem Leitfaden stehen die Änderungen, die ich am häufigsten vornehme, in der Reihenfolge, in der ich sie prüfe.

1. Jeden Spaltennamen in Anführungszeichen setzen

An dieser Stelle stolpert jeder als Erstes. HANA wandelt Namen ohne Anführungszeichen in Großbuchstaben um. Die Spaltennamen in SAP Business One sind jedoch in gemischter Schreibweise angelegt: CardCode, DocTotal, U_MyField. Aus T0.CardCode wird also T0.CARDCODE, und HANA findet die Spalte nicht.

Die Lösung sind doppelte Anführungszeichen um den Namen:

SELECT T0."DocNum", T0."CardCode", T0."DocTotal"
FROM "OINV" T0
WHERE T0."CANCELED" = 'N'

Daraus ergeben sich zwei Regeln:

  • Doppelte Anführungszeichen kennzeichnen einen Bezeichner. Einfache Anführungszeichen kennzeichnen eine Zeichenkette. Auf SQL Server kam man mit "N" manchmal noch durch. Auf HANA ist "N" eine Spalte namens N, und die Abfrage schlägt fehl.
  • Auch Aliasnamen gehören in Anführungszeichen, wenn die Schreibweise erhalten bleiben soll: AS "Customer Name".

2. Die gängigen Funktionen ersetzen

Die folgenden T-SQL-Funktionen finde ich in nahezu jeder SAP-B1-Datenbank, daneben ihre Entsprechungen in HANA.

SQL Server (T-SQL)SAP HANAHinweis
ISNULL(T0.Comments, '')IFNULL(T0."Comments", '')COALESCE funktioniert auf beiden
GETDATE()CURRENT_TIMESTAMPCURRENT_DATE für das reine Datum
DATEADD(day, 30, T0.DocDate)ADD_DAYS(T0."DocDate", 30)Außerdem ADD_MONTHS, ADD_YEARS
DATEDIFF(day, T0.DocDueDate, GETDATE())DAYS_BETWEEN(T0."DocDueDate", CURRENT_DATE)Gleiche Argumentreihenfolge: von, bis
CONVERT(varchar, T0.DocDate, 103)TO_NVARCHAR(T0."DocDate", 'DD/MM/YYYY')Formatstring statt Stilnummer
T0.CardCode + ' - ' + T0.CardNameT0."CardCode" || ' - ' || T0."CardName"+ addiert auf HANA nur Zahlen
SELECT TOP 10 ...SELECT TOP 10 ... oder LIMIT 10TOP funktioniert auf HANA
#Temp / SELECT INTOTabellenvariable oder CREATE LOCAL TEMPORARY TABLEErfordert SQLScript
SELECT GETDATE()SELECT CURRENT_TIMESTAMP FROM DUMMYHANA verlangt eine FROM-Klausel
RIGHT(REPLICATE('0', 8) + T0.CardCode, 8)LPAD(T0."CardCode", 8, '0')Auffüllen mit Nullen; RPAD füllt rechts auf. Ein alleinstehendes REPLICATE('-', 10) wird zu LPAD('', 10, '-')

Ein vollständiges Vorher-nachher-Beispiel anhand einer typischen Abfrage für überfällige Ausgangsrechnungen:

-- SQL Server
SELECT TOP 50
  T0.DocNum,
  T0.CardCode + ' - ' + T0.CardName AS Customer,
  CONVERT(varchar, T0.DocDueDate, 103) AS DueDate,
  DATEDIFF(day, T0.DocDueDate, GETDATE()) AS DaysLate,
  ISNULL(T0.Comments, '') AS Comments
FROM OINV T0
WHERE T0.DocStatus = 'O'
  AND T0.DocDueDate < DATEADD(day, -30, GETDATE())
ORDER BY DaysLate DESC
-- SAP HANA
SELECT TOP 50
  T0."DocNum",
  T0."CardCode" || ' - ' || T0."CardName" AS "Customer",
  TO_NVARCHAR(T0."DocDueDate", 'DD/MM/YYYY') AS "DueDate",
  DAYS_BETWEEN(T0."DocDueDate", CURRENT_DATE) AS "DaysLate",
  IFNULL(T0."Comments", '') AS "Comments"
FROM "OINV" T0
WHERE T0."DocStatus" = 'O'
  AND T0."DocDueDate" < ADD_DAYS(CURRENT_DATE, -30)
ORDER BY "DaysLate" DESC

Sie können Ihr eigenes T-SQL in unseren kostenlosen SQL-to-HANA-Converter einfügen und erhalten einen ersten Entwurf dieser Änderungen.

3. Die B1-Parameter unverändert lassen

Gespeicherte Abfragen, die beim Benutzer Werte abfragen, arbeiten mit [%0], [%1] und so weiter. SAP Business One ersetzt diese Platzhalter, bevor das SQL die Datenbank erreicht. Auf HANA bleiben sie deshalb gleich:

SELECT T0."DocNum", T0."DocDate", T0."DocTotal"
FROM "ORDR" T0
WHERE T0."DocDate" >= [%0]
  AND T0."DocDate" <= [%1]

Formatierte Suchen funktionieren genauso. Verweise wie $[$38.1.0] oder $[ORDR."CardCode"] füllt der Client aus. Umstellen müssen Sie nur das SQL drumherum. Achten Sie auf die Anführungszeichen innerhalb des Feldverweises: Für Tabelle und Spalte gelten dieselben HANA-Regeln.

4. Stored Procedures und temporäre Tabellen brauchen SQLScript

Hier hilft Suchen und Ersetzen nicht mehr weiter. T-SQL-Prozeduren verwenden @variables, #temp-Tabellen, SELECT INTO, WHILE-Schleifen und Cursor. HANA-Prozeduren werden in SQLScript geschrieben, und das ist anders aufgebaut:

  • Variablen werden mit DECLARE deklariert und mit vorangestelltem Doppelpunkt gelesen: :lv_total.
  • Zwischenergebnisse landen in der Regel in Tabellenvariablen (lt_open = SELECT ...;), nicht in temporären Tabellen.
  • HANA kennt zwar lokale temporäre Tabellen (ebenfalls mit # benannt), diese müssen Sie aber zuerst mit expliziten Spalten anlegen. Ein SELECT INTO #temp gibt es nicht.
  • Jede Anweisung endet mit einem Semikolon.
-- SQLScript: open order value per customer
CREATE PROCEDURE "KN_OPEN_ORDERS" (IN p_from DATE)
LANGUAGE SQLSCRIPT AS
BEGIN
  lt_orders = SELECT "CardCode", "DocTotal"
              FROM "ORDR"
              WHERE "DocStatus" = 'O' AND "DocDate" >= :p_from;

  SELECT "CardCode", SUM("DocTotal") AS "OpenValue"
  FROM :lt_orders
  GROUP BY "CardCode";
END;

T-SQL-Skripte, die Sie von Hand ausführen und die mit DECLARE @x beginnen, haben außerhalb einer Prozedur keine direkte Entsprechung in HANA. Verpacken Sie sie in einen anonymen Block, DO BEGIN ... END;. Er führt SQLScript einmalig aus, ohne eine Prozedur anzulegen:

-- T-SQL
DECLARE @from DATE = '2026-01-01';
SELECT CardCode, SUM(DocTotal) FROM ORDR WHERE DocDate >= @from GROUP BY CardCode;

-- SQLScript anonymous block
DO BEGIN
  DECLARE lv_from DATE := '2026-01-01';
  SELECT "CardCode", SUM("DocTotal") AS "Total"
  FROM "ORDR"
  WHERE "DocDate" >= :lv_from
  GROUP BY "CardCode";
END;

Anonyme Blöcke unterstützen dieselben Anweisungen wie ein Prozedurrumpf, lassen sich aber nicht innerhalb einer Prozedur oder Funktion verwenden.

Prozeduren, die stark auf Cursorn aufbauen, lohnt es sich bei dieser Gelegenheit als mengenbasierte Abfragen neu zu entwerfen. HANA dankt es Ihnen.

5. SBO_SP_TransactionNotification

Auf HANA liefert SAP Business One die Transaction Notification als SQLScript-Prozedur aus. Sie erhält dieselben Eingaben wie bisher (Objekttyp, Transaktionstyp, Schlüsselspalten und deren Werte) und gibt Fehlercode und Fehlermeldung am Ende mit einem SELECT ... FROM DUMMY zurück. Die vollständigen Regeln im direkten Vergleich finden Sie in diesen TransactionNotification-Beispielen für SQL Server und HANA.

Ihre Prüfblöcke aus T-SQL müssen innerhalb dieser Prozedur neu geschrieben werden. Ein typischer Block sieht so aus:

IF :object_type = '17' AND (:transaction_type = 'A' OR :transaction_type = 'U') THEN
  SELECT COUNT(*) INTO cnt
  FROM "ORDR"
  WHERE "DocEntry" = :list_of_cols_val_tab_del
    AND IFNULL("NumAtCard", '') = '';
  IF :cnt > 0 THEN
    error := 1;
    error_message := 'Customer reference is required';
  END IF;
END IF;

Deklarieren Sie cnt am Anfang der Prozedur. Halten Sie jede Regel klein und testen Sie Hinzufügen und Aktualisieren getrennt. Ein einziger Syntaxfehler an dieser Stelle blockiert sämtliche Belege im Mandanten. Spielen Sie die Prozedur deshalb außerhalb der Arbeitszeiten ein.

6. Commands in Crystal Reports

Crystal Reports, die auf SQL Server erstellt wurden, verwenden häufig einen Command (eine eingefügte SQL-Anweisung) oder rufen eine Stored Procedure auf. Beides enthält T-SQL. Für jeden Bericht gilt:

  1. Das SQL des Commands bzw. die Prozedur in HANA-Syntax umwandeln.
  2. Den Bericht über Database > Set Datasource Location auf die HANA-Datenquelle umstellen, mit HANA-Verbindung, Anmeldedaten und dem Schema des Mandanten.
  3. Prüfen, ob die Parameterfelder weiterhin den Parametern des Commands zugeordnet sind.
  4. Den Bericht im SAP-Business-One-Client für HANA in der Vorschau öffnen und die Ausgabe mit der SQL-Server-Version vergleichen.

Berichte, die direkt auf Tabellen ohne Commands aufbauen, brauchen meist nur Schritt 2.

7. Ein Testvorgehen, das Fehler aufdeckt

Eine umgewandelte Abfrage, die läuft, ist noch lange keine umgewandelte Abfrage, die stimmt. Die Verkettung von Zeichenketten mit + ist die klassische Falle: Auf HANA schlägt sie entweder fehl oder versucht, die Werte als Zahlen zu addieren. Datumsformate sind eine weitere.

  1. Zuerst eine Bestandsaufnahme. Exportieren Sie die Liste der gespeicherten Abfragen (OUQR), formatierten Suchen (CSHS), Alarme, Crystal Reports, benutzerdefinierten Prozeduren und die Transaction Notification. Notieren Sie, wer was nutzt. Vieles wird gar nicht mehr verwendet und kann entfallen.
  2. In Paketen nach Typ umstellen: einfache Abfragen, formatierte Suchen, Berichte, dann Prozeduren.
  3. Beide Versionen ausführen, SQL Server und HANA, jeweils auf einer Kopie desselben Datenbestands.
  4. Zeilenanzahl und Summen vergleichen. Wenn sich die Summen von DocTotal oder die Anzahlen unterscheiden, klären Sie die Ursache, bevor Sie weitermachen.
  5. Grenzfälle testen. NULL-Werte, stornierte Belege, Fremdwährung und Belege über einen Jahreswechsel hinweg.
  6. Abnahme durch die Key-User: Lassen Sie die Berichte, mit denen sie täglich arbeiten, von ihnen freigeben.

Als Ausgangspunkt enthält unsere SAP-B1-Abfragebibliothek gängige Abfragen in T-SQL- und HANA-Syntax, und der SQL-to-HANA-Converter beschleunigt den ersten Durchgang für Ihre eigenen Abfragen.

Womit Sie rechnen sollten

Einfache gespeicherte Abfragen dauern jeweils wenige Minuten. Formatierte Suchen ähnlich. Berichte mit Commands dauern wegen der Tests länger. Stored Procedures und die Transaction Notification kosten die meiste Zeit und bergen das größte Risiko. Nehmen Sie sie deshalb als Erstes in Angriff, nicht als Letztes.

Wenn Sie eine Umstellung auf HANA planen und Ihre Abfragen, Berichte und Prüfregeln umgewandelt und getestet haben möchten, kontaktieren Sie Kodenova mit einer Liste dessen, was bei Ihnen im Einsatz ist.

Quellen

Passende Leistungen

FAQ

Häufige Fragen

Funktionieren SAP-Business-One-Abfragen auf HANA ohne Änderungen?

Nur die einfachsten. Jede Abfrage, die Spaltennamen in gemischter Schreibweise ohne Anführungszeichen, ISNULL, GETDATE, DATEADD, CONVERT oder + für Zeichenketten verwendet, schlägt auf HANA fehl oder liefert falsche Ergebnisse. Abfragen aus dem Abfragegenerator brauchen meist weniger Anpassungen.

Warum meldet HANA einen ungültigen Spaltennamen, obwohl die Spalte existiert?

HANA wandelt Bezeichner ohne Anführungszeichen in Großbuchstaben um. Die Spalten in SAP Business One sind in gemischter Schreibweise angelegt, etwa CardCode. Sie müssen also T0."CardCode" mit doppelten Anführungszeichen schreiben. Tabellennamen wie OINV sind bereits großgeschrieben, aber auch sie in Anführungszeichen zu setzen, ist eine sichere Gewohnheit.

Funktionieren die Parameter [%0] in gespeicherten Abfragen auch auf HANA?

Ja. Parameter im Stil von [%0] und [%1] verarbeitet SAP Business One selbst, bevor das SQL die Datenbank erreicht. Sie bleiben also unverändert. Anpassen müssen Sie nur das SQL drumherum.

Gibt es ein Tool, das T-SQL automatisch in HANA-SQL umwandelt?

SAP hat auf GitHub ein Query Migration Tool veröffentlicht, das einen großen Teil von T-SQL umwandelt. Das Projekt ist jedoch archiviert, und SAP weist darauf hin, dass Sie das Ergebnis prüfen müssen. Unser kostenloser SQL-to-HANA-Converter deckt die gängigen SAP-B1-Muster ab. In beiden Fällen sollte ein Mensch jede umgewandelte Abfrage testen.

Was ist der schwierigste Teil der Migration?

Stored Procedures, temporäre Tabellen, Cursor und SBO_SP_TransactionNotification. Hier ist eine saubere Neuentwicklung in SQLScript nötig, kein Suchen und Ersetzen.

Bereit für den Start?

Sagen Sie uns, was Sie brauchen. Sie erhalten eine klare technische Antwort, einen festen Leistungsumfang und einen Preis, in der Regel innerhalb von 24 Stunden.