Avvii un progetto

Migrare SAP Business One da SQL Server a HANA: come convertire query, report e ricerche formattate

By Zain Abbas, Kodenova · Updated

Short answerHANA usa un SQL in stile ANSI, quindi la maggior parte delle query di SAP Business One richiede modifiche piccole ma rigorose: virgolette sui nomi delle colonne (T0."CardCode"), IFNULL al posto di ISNULL, CURRENT_TIMESTAMP al posto di GETDATE, ADD_DAYS e DAYS_BETWEEN al posto di DATEADD e DATEDIFF, TO_NVARCHAR al posto di CONVERT e || al posto di + per concatenare stringhe. Le query semplici si convertono in pochi minuti. Stored procedure, tabelle temporanee e SBO_SP_TransactionNotification vanno riscritte in SQLScript e testate sugli stessi dati.

Perché le query si bloccano su HANA

Quando un’azienda sposta SAP Business One da Microsoft SQL Server a SAP HANA, i dati migrano senza problemi. L’SQL personalizzato no. Query salvate, alert, ricerche formattate, comandi di Crystal Reports, SQL degli add-on e transaction notification contengono tutti T-SQL, e HANA non parla T-SQL.

La maggior parte delle modifiche è piccola. Il problema è che sono tante, e una sola virgoletta dimenticata blocca l’intera query. Questa guida elenca le modifiche che facciamo più spesso, nell’ordine in cui le verifichiamo.

1. Mettere le virgolette a ogni nome di colonna

È la modifica che coglie tutti di sorpresa per prima. HANA converte in maiuscolo i nomi senza virgolette. I nomi delle colonne di SAP Business One hanno maiuscole e minuscole: CardCode, DocTotal, U_MyField. Così T0.CardCode diventa T0.CARDCODE e HANA non lo trova.

La soluzione sono le virgolette doppie intorno al nome:

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

Ne derivano due regole:

  • Le virgolette doppie indicano un identificatore. Gli apici singoli indicano una stringa. In SQL Server a volte si poteva scrivere "N"; su HANA "N" è una colonna chiamata N e la query fallisce.
  • Anche gli alias vanno tra virgolette se vuole mantenerne le maiuscole: AS "Customer Name".

2. Sostituire le funzioni più comuni

Queste sono le funzioni T-SQL che troviamo in quasi ogni database SAP B1, con i loro equivalenti HANA.

SQL Server (T-SQL)SAP HANANota
ISNULL(T0.Comments, '')IFNULL(T0."Comments", '')COALESCE funziona su entrambi
GETDATE()CURRENT_TIMESTAMPUsi CURRENT_DATE per la sola data
DATEADD(day, 30, T0.DocDate)ADD_DAYS(T0."DocDate", 30)Esistono anche ADD_MONTHS, ADD_YEARS
DATEDIFF(day, T0.DocDueDate, GETDATE())DAYS_BETWEEN(T0."DocDueDate", CURRENT_DATE)Stesso ordine degli argomenti: da, a
CONVERT(varchar, T0.DocDate, 103)TO_NVARCHAR(T0."DocDate", 'DD/MM/YYYY')La stringa di formato sostituisce il numero di stile
T0.CardCode + ' - ' + T0.CardNameT0."CardCode" || ' - ' || T0."CardName"Su HANA + somma solo numeri
SELECT TOP 10 ...SELECT TOP 10 ... oppure LIMIT 10TOP funziona su HANA
#Temp / SELECT INTOVariabile di tabella o CREATE LOCAL TEMPORARY TABLERichiede SQLScript
SELECT GETDATE()SELECT CURRENT_TIMESTAMP FROM DUMMYHANA richiede una clausola FROM
RIGHT(REPLICATE('0', 8) + T0.CardCode, 8)LPAD(T0."CardCode", 8, '0')Riempimento con zeri; RPAD riempie a destra. Un semplice REPLICATE('-', 10) diventa LPAD('', 10, '-')

Un esempio completo prima e dopo, da una tipica query sulle fatture scadute:

-- 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

Può incollare il suo T-SQL nel nostro convertitore gratuito da SQL a HANA per ottenere una prima bozza di queste modifiche.

3. Lasciare invariati i parametri di B1

Le query salvate che chiedono un input all’utente usano [%0], [%1] e così via. SAP Business One li sostituisce prima che l’SQL arrivi al database, quindi su HANA restano uguali:

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

Le ricerche formattate funzionano allo stesso modo. Riferimenti come $[$38.1.0] o $[ORDR."CardCode"] vengono compilati dal client. Va convertito solo l’SQL che li circonda. Faccia attenzione alle virgolette dentro il riferimento al campo: tabella e colonna seguono le stesse regole di HANA.

4. Stored procedure e tabelle temporanee richiedono SQLScript

Qui il trova e sostituisci smette di funzionare. Le procedure T-SQL usano @variabili, tabelle #temp, SELECT INTO, cicli WHILE e cursori. Le procedure HANA si scrivono in SQLScript, che ha una struttura diversa:

  • Le variabili si dichiarano con DECLARE e si leggono con il prefisso dei due punti: :lv_total.
  • I risultati intermedi di solito finiscono in variabili di tabella (lt_open = SELECT ...;), non in tabelle temporanee.
  • HANA ha tabelle temporanee locali (anch’esse con # nel nome), ma vanno prima create con colonne esplicite. Non esiste SELECT INTO #temp.
  • Ogni istruzione termina con un punto e virgola.
-- 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;

Gli script T-SQL eseguiti a mano con DECLARE @x in cima non hanno un equivalente HANA diretto fuori da una procedura. Li racchiuda in un blocco anonimo, DO BEGIN ... END;, che esegue SQLScript una volta senza creare una procedura:

-- 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;

I blocchi anonimi supportano le stesse istruzioni del corpo di una procedura, ma non si possono usare dentro una procedura o una funzione.

Già che ci si trova, conviene riprogettare le procedure piene di cursori come query basate su insiemi. HANA ne trae vantaggio.

5. SBO_SP_TransactionNotification

Su HANA, SAP Business One fornisce la transaction notification come procedura SQLScript. Riceve gli stessi input di prima (tipo di oggetto, tipo di transazione, colonne chiave e valori) e alla fine restituisce codice e messaggio di errore con una SELECT ... FROM DUMMY. Per le regole complete a confronto, veda questi esempi di TransactionNotification per SQL Server e HANA.

I blocchi di validazione T-SQL vanno riscritti all’interno di quella procedura. Un blocco tipico si presenta così:

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;

Dichiari cnt all’inizio della procedura. Mantenga ogni regola piccola e testi separatamente inserimento e modifica. Quando una regola blocca un documento registrato da un’integrazione, la chiamata DI API o Service Layer fallisce e il suo messaggio torna nel testo dell’errore; come leggerlo è spiegato in codici di errore della DI API. Un solo errore di sintassi qui blocca tutti i documenti della società, quindi la distribuisca fuori dall’orario di lavoro.

6. Comandi di Crystal Reports

I Crystal Reports costruiti su SQL Server usano spesso un Command (un’istruzione SQL incollata) o richiamano una stored procedure. Entrambi contengono T-SQL. Per ogni report:

  1. Converta l’SQL del comando o la procedura nella sintassi HANA.
  2. Punti il report alla fonte dati HANA con Database > Set Datasource Location, usando la connessione HANA, le credenziali e lo schema della società.
  3. Verifichi che i campi parametro corrispondano ancora ai parametri del comando.
  4. Visualizzi l’anteprima nel client SAP Business One per HANA e confronti il risultato con la versione SQL Server.

I report basati su semplici tabelle, senza comandi, di solito richiedono solo il passo 2.

7. Un approccio di test che intercetta gli errori

Una query convertita che gira non equivale a una query convertita corretta. La concatenazione di stringhe con + è la trappola classica: su HANA può fallire oppure tentare di sommare i valori come numeri. I formati delle date sono un’altra.

  1. Prima l’inventario. Esporti l’elenco di query salvate (OUQR), ricerche formattate (CSHS), alert, report Crystal, procedure utente e transaction notification. Annoti chi usa ciascun elemento. Molti risulteranno inutilizzati e si potranno eliminare.
  2. Converta a lotti per tipo: query semplici, ricerche formattate, report, poi procedure.
  3. Esegua entrambe le versioni su una copia degli stessi dati, SQL Server e HANA.
  4. Confronti numero di righe e totali. Se le somme di DocTotal o i conteggi differiscono, scopra perché prima di proseguire.
  5. Testi i casi limite. Valori NULL, documenti annullati, valuta estera e documenti a cavallo di fine anno.
  6. Faccia approvare agli utenti chiave i report che usano ogni giorno.

Come punto di partenza, la nostra libreria di query SAP B1 contiene query comuni scritte sia in sintassi T-SQL sia HANA, e il convertitore da SQL a HANA accelera il primo passaggio sulle sue.

Che cosa aspettarsi

Le query salvate semplici richiedono pochi minuti ciascuna. Le ricerche formattate sono simili. I report con comandi richiedono più tempo per via dei test. Stored procedure e transaction notification richiedono più tempo e comportano più rischi, quindi le pianifichi per prime, non per ultime.

Se sta pianificando il passaggio a HANA e vuole che query, report e validazioni vengano convertiti e testati, contatti Kodenova con l’elenco di ciò che ha.

Sources

Related services

FAQ

Frequently asked questions

Le query di SAP Business One funzionano su HANA senza modifiche?

Solo le più semplici. Qualsiasi query che usa nomi di colonna con maiuscole e minuscole senza virgolette, ISNULL, GETDATE, DATEADD, CONVERT o + per le stringhe fallirà o darà risultati errati su HANA. Le query create con il Query Generator di solito richiedono meno modifiche.

Perché HANA segnala un nome di colonna non valido se la colonna esiste?

HANA converte in maiuscolo gli identificatori senza virgolette. Le colonne di SAP Business One hanno maiuscole e minuscole, come CardCode, quindi deve scrivere T0."CardCode" con le virgolette doppie. I nomi di tabella come OINV sono già in maiuscolo, ma mettere le virgolette anche a questi è una buona abitudine.

I parametri [%0] delle query salvate funzionano ancora su HANA?

Sì. I parametri di tipo [%0], [%1] vengono gestiti da SAP Business One prima che l'SQL arrivi al database, quindi li può mantenere. Va modificato solo l'SQL che li circonda.

Esiste uno strumento che converte automaticamente il T-SQL in SQL HANA?

SAP ha pubblicato su GitHub un Query Migration Tool che converte buona parte del T-SQL, ma il progetto è archiviato e SAP avverte che il risultato va verificato. Il nostro convertitore gratuito da SQL a HANA gestisce gli schemi più comuni di SAP B1. In ogni caso, una persona dovrebbe testare ogni query convertita.

Qual è la parte più difficile della migrazione?

Stored procedure, tabelle temporanee, cursori e SBO_SP_TransactionNotification. Richiedono una vera riscrittura in SQLScript, non un trova e sostituisci.

Iniziamo?

Ci descriva di cosa ha bisogno. Riceverà una risposta tecnica chiara, un perimetro definito e un prezzo, di norma entro 24 ore.