AL Synchronize Databases - Guida utente
Configurazione e uso in Business Central.
1. Concetti in un minuto
- Un Nodo (Node) è la connessione a un database esterno: tipo (PostgreSQL o Microsoft SQL), server, porta, database e credenziali.
- Un Node Group (SDB) raggruppa i nodi serviti da una stessa istanza dei servizi locali e ne definisce i ritmi di polling (Restart Interval, Refresh Interval, Record Download Number).
- Una Interfaccia (Node Interface) collega UNA tabella di Business Central a UNA tabella del nodo: elenco campi, filtri, direzione (Export to DB / Import from DB) e campi di sincronizzazione.
- Il Buffer di sincronizzazione è la coda (e insieme il registro) delle operazioni da eseguire sul database esterno: per ogni record contiene la query SQL già pronta.
- Il lavoro sul database esterno lo fanno due servizi Windows locali, installati con l'AppLibra License Manager: "DD - Esporta da Business Central" (export) e "DD - Importa in Business Central" (import). Business Central non apre mai connessioni dirette verso il database esterno: i servizi dialogano con Business Central tramite la Web API dell'app e con il database di destinazione tramite la sua connessione nativa.
Il flusso di export in breve: modifica dati in BC -> global trigger -> riga nel buffer con la SQL pronta -> il servizio di export legge il buffer via Web API, esegue la SQL sul database esterno e marca la riga come eseguita (Skip).
2. Prerequisiti
- Business Central versione 25.0 o superiore (Cloud/SaaS).
- Le dipendenze AppLibra installate automaticamente con l'app: AL License and Trial Management, AL Role Center.
- L'AppLibra License Manager (il gestore locale delle app AppLibra, lo stesso usato per AL Bridge / AL Message Passing) installato su una macchina Windows che raggiunga sia la Web API di Business Central sia il database di destinazione. Da lì si installano e avviano i servizi "DD - Esporta da Business Central" e/o "DD - Importa in Business Central", configurati con URL della Web API, società, credenziali e ID del Node Group da servire.
- Un utente Business Central dedicato ai servizi, con accesso alla Web API.
- Sul database esterno: un login con permessi DDL (creazione tabelle) e DML (insert/update/delete) sul database di destinazione.
3. Configurazione
3.1 Attivare la licenza
Cerca Synchronize Database Setup in Tell Me (Alt+Q), aprilo ed esegui Aggiungi Licenza per attivare l'app (trial o completa). Le pagine dell'app sono raggiungibili anche dalla sezione Synchronize Databases del Role Center AppLibra.

3.2 Node Group (SDB)
Cerca Node Groups (SDB). Un Node Group (il gruppo NAS) è il "contratto" tra Business Central e un'istanza dei servizi locali:
| Campo | Scopo |
|---|---|
| ID | Identificativo del gruppo. È l'ID che indichi nella configurazione del servizio locale: quel servizio lavora SOLO i nodi e le interfacce di questo gruppo. |
| Restart Interval | Durata di un ciclo di lavoro del servizio. A ogni riavvio di ciclo il servizio rilegge la configurazione: nodi, intervalli e password. |
| Refresh Interval | Pausa tra una passata di polling e la successiva all'interno del ciclo. |
| Record Download Number | Numero massimo di righe di buffer scaricate a ogni passata (default 500). |
Se non esiste, il Node Group viene creato automaticamente al salvataggio del primo nodo (con Restart Interval di 1 ora e Refresh Interval di 100 ms); rivedi comunque i valori.
3.3 Servizi locali
Dall'AppLibra License Manager, sezione servizi, installa:
- DD - Esporta da Business Central: legge il buffer e scrive sul database esterno; gestisce anche la creazione/drop delle tabelle (vedi 3.6).
- DD - Importa in Business Central: legge dal database esterno le righe marcate dal sistema terzo e le riporta in Business Central.
Servono entrambi solo se il flusso è bidirezionale. Ogni istanza di servizio è legata a una società e a un Node Group.
3.4 Creare un Nodo
Cerca Node e crea una scheda per ogni database di destinazione:

| Campo | Scopo |
|---|---|
| No. / Description | Identificativo e descrizione del nodo. |
| Synchronize Type (Database Interface) | Il motore di destinazione: PostgreSQL o Microsoft SQL. Determina la sintassi SQL generata e il quoting degli identificatori. |
| Server / Port / Database | Coordinate del database esterno. |
| User ID / Password | Credenziali usate dal servizio per connettersi. La password è salvata in Isolated Storage di Business Central e consegnata al servizio via Web API. |
| Trusted Connection / Domain | Autenticazione Windows (solo Microsoft SQL): attivando Trusted Connection va indicato il dominio. |
| Authentication Type | Web o Windows. |
| Encrypted | Richiede la cifratura della connessione al database. |
| Decimal Symbol Is Comma | Gestione del separatore decimale nella formattazione dei valori. |
| Node Group ID | Il Node Group (SDB) che serve questo nodo. |
| Update Interval | Ritmo (in millisecondi) con cui il servizio interroga questo nodo, se non specificato sull'interfaccia. |
| Status | Disable/Enable. Con Enable i campi di connessione diventano non modificabili; per abilitare servono Node Group ID valido e Update Interval. |
Nella parte bassa della scheda nodo compare il Node Interface Log con gli errori più recenti riportati dal servizio (vedi sezione 6).
3.5 Table Setup
Cerca Table Setup e registra le tabelle di Business Central da sincronizzare, indicando quali eventi devono alimentare il buffer:

| Campo | Scopo |
|---|---|
| Table ID / Table Caption | La tabella BC (lookup su tutti gli oggetti). |
| OnDatabaseInsert / OnDatabaseModify / OnDatabaseDelete / OnDatabaseRename | Quali trigger di database attivare per la tabella. Consigliato attivarli tutti. |
Il Table Setup è il prerequisito dell'interfaccia: il campo Table ID dell'interfaccia si aggancia alle tabelle registrate qui. Alla cancellazione dell'ultima interfaccia su una tabella, la riga di Table Setup viene rimossa.
Nota: la piattaforma legge la configurazione dei trigger all'apertura della società. Dopo aver aggiunto una tabella nuova, le sessioni già aperte potrebbero non intercettare le modifiche finché non vengono riaperte.
3.6 Creare un'Interfaccia (Node Interface)
Dalla scheda nodo esegui Node Interface e crea una riga per ogni tabella; apri poi la Node Interface Card:

- Table ID: scegli la tabella (tra quelle in Table Setup). L'Interface Name si precompila con la caption della tabella: è il nome della tabella che verrà creata sul database esterno. Rivedilo subito, prima di creare la tabella (l'interfaccia non si può rinominare).
- Alla creazione l'app genera automaticamente l'elenco campi: i campi della chiave primaria sono marcati Key Field e sempre sincronizzati; gli altri campi sono elencati ma non selezionati.
- Nel subform seleziona Synchronize sui campi da portare sul database esterno. L'azione Select/Deselect Field Synchronize inverte la selezione di tutti i campi non chiave (a interfaccia disabilitata). Reset Field List rigenera l'elenco campi da zero (utile dopo modifiche allo schema della tabella BC); attenzione: azzera le personalizzazioni fatte sui campi.
- Facoltativo, per campo:
- Filters: esporta solo i record il cui campo ha uno dei valori indicati (valori alternativi separati da
|, es.10000|20000). - Validate Field: in import, esegue la validazione BC del campo.
- Ammetti valore NULL (Allow NULL Value): la colonna esterna nasce nullable e i valori BC "vuoti" (0, stringa vuota, false...) vengono esportati come NULL.
- Filters: esporta solo i record il cui campo ha uno dei valori indicati (valori alternativi separati da
- Imposta la direzione: Export to DB (BC -> esterno) e/o Import from DB (esterno -> BC), e l'Update Interval dell'interfaccia.
Naming: consigli per PostgreSQL
Gli identificatori generati dall'app sono sempre quotati: "nome" su PostgreSQL, [nome] su Microsoft SQL. Su PostgreSQL un identificatore quotato è case-sensitive: "Customer" e customer sono due oggetti diversi, e per interrogare "Customer" dovrai sempre scrivere le virgolette rispettando le maiuscole. Per questo su nodi PostgreSQL conviene usare nomi tutti minuscoli e senza spazi (es. customer, sales_invoice_line) sia per l'Interface Name sia per gli eventuali nomi campo personalizzati: le query manuali sul database restano semplici. I nomi campo si possono modificare direttamente nel subform (il quoting viene riapplicato in automatico).
Campi di sincronizzazione
Con Use synchronization fields attivo (default), la tabella esterna riceve cinque colonne di servizio che governano il protocollo bidirezionale:
| Colonna (nome di default) | Significato |
|---|---|
| externalId | Chiave primaria della tabella esterna (uuid); mappa il record esterno sul System ID del record BC tramite il buffer. |
| serverModification | Impostata a true da ogni scrittura proveniente da BC. |
| clientModification | Impostata a true DAL SISTEMA ESTERNO per chiedere l'import in BC della riga. |
| serverDeletion / clientDeletion | Come sopra, per le cancellazioni; clientDeletion = true fa eliminare il record in BC. |
I nomi delle colonne si possono personalizzare nei cinque campi "... Field name" della scheda. L'import da database esterno richiede i campi di sincronizzazione; senza di essi l'interfaccia funziona da solo export, con insert/update per chiave primaria.
Altre opzioni dell'interfaccia
| Campo / azione | Scopo |
|---|---|
| Import Single Row | In import processa una riga per passata (throttling). |
| Select rows with NOLOCK | Solo Microsoft SQL: legge le righe da importare con NOLOCK (letture sporche possibili; usare con cautela). |
| Post On After Data Import | Dopo l'import di una riga pubblica un business event (OnPostAfterImport) per elaborazioni custom (es. registrazione). |
| Delete On Post After Import | Dopo l'elaborazione post-import elimina il record in BC e la riga sul database esterno (richiede Post On After Data Import). |
| Log SQL | Registra ogni query accodata nella tabella Synchronize SQL Log (vedi sezione 6). |
| Header Table Id / Bulk | Operazioni bulk testata/righe: le query delle righe vengono accodate alla query della testata (Header Table Id sulla riga punta all'interfaccia della testata, marcata Bulk). |
| Copy Node Interface | Copia la configurazione (campi inclusi) da un'interfaccia della stessa tabella su un altro nodo. |
| Export query | Scarica lo script SQL corrente dell'interfaccia (il CREATE TABLE generato). |
| Execute truncate | Accoda un TRUNCATE TABLE della tabella esterna e svuota il buffer dell'interfaccia. Irreversibile sul database di destinazione. |
Non usare il campo "Export All Records": è obsoleto e non è mai stato implementato; al suo posto c'è l'azione Export All New Records (sezione 4.2).
3.7 Ciclo di vita SQL Status (chi crea la tabella esterna)
Il campo SQL Status dell'interfaccia governa la creazione della tabella sul database esterno. La tabella NON viene creata da Business Central: la crea il servizio locale.
- Alla creazione l'interfaccia è in New: in questo stato non può essere abilitata.
- A configurazione finita imposta SQL Status = Create Interface (oppure Drop and Recreate Interface per ricreare da zero, o Drop Interface per eliminare la tabella esterna).
- Abilita l'interfaccia (Status = Enable). Il servizio del verso dell'interfaccia (export o import) vede lo stato, chiede a Business Central lo script (CREATE TABLE con colonne di sincronizzazione e indici, o DROP), lo esegue sul database esterno in transazione e aggiorna lo stato:
- Create / Drop and Recreate -> Created;
- Drop -> New (e l'interfaccia torna disabilitata).
- Da Created l'interfaccia è operativa. Qualsiasi valore di SQL Status diverso da Created disabilita automaticamente l'interfaccia.
Se lo stato resta su Create Interface, il servizio non sta lavorando: verifica che sia in esecuzione, che serva il Node Group giusto e controlla il Node Interface Log per errori di connessione o SQL.
3.8 Abilitare la sincronizzazione
- Abilita il nodo (Status = Enable sulla scheda nodo).
- Abilita le interfacce (Status = Enable, con SQL Status = Created).
Le righe di buffer hanno uno Status proprio che rispecchia nodo+interfaccia: solo con entrambi abilitati le righe sono Enable e il servizio le lavora. Disabilitare il nodo o l'interfaccia sospende la sincronizzazione senza perdere la coda.
4. Uso quotidiano
4.1 Export incrementale automatico
A regime non serve fare nulla: ogni insert, modifica o cancellazione sulle tabelle configurate (secondo i flag del Table Setup) accoda una riga nel buffer con la query SQL già generata (INSERT ... ON CONFLICT ... UPDATE su PostgreSQL, equivalente su Microsoft SQL; DELETE per le cancellazioni). Il servizio di export la esegue e marca la riga.
I filtri dell'interfaccia vengono applicati alla fonte: i record che non passano i filtri non entrano nel buffer.
4.2 Export All New Records (caricamento iniziale)
Sulla Node Interface Card, azione Export All New Records (gruppo Functions): accoda per l'export tutti i record della tabella che non sono mai stati esportati da questa interfaccia.
- Il buffer esistente è preservato: i record già esportati (righe Skip) e quelli già in coda vengono saltati.
- È quindi sicura da rilanciare più volte: non re-invia dati già presenti nella destinazione.
- Richiede nodo e interfaccia abilitati (altrimenti le righe nascerebbero disabilitate e il servizio non le vedrebbe mai).
- Al termine un messaggio riepiloga quanti record sono stati accodati sul totale.
Usala dopo la prima abilitazione dell'interfaccia per caricare lo storico, o per recuperare i record creati mentre l'interfaccia era disabilitata.
4.3 Import dal database esterno
Con Import from DB attivo, il sistema esterno chiede la sincronizzazione verso Business Central marcando le proprie righe:
- il sistema esterno scrive/aggiorna la riga nella tabella esterna e imposta clientModification = true (oppure clientDeletion = true per far eliminare il record in BC);
- il servizio di import seleziona le righe marcate (una sola per passata se Import Single Row) e le invia a Business Central: il record viene creato o aggiornato campo per campo (con validazione dove Validate Field è attivo), o eliminato se clientDeletion;
- il servizio riporta la riga esterna allo stato "sincronizzato" (serverModification = true, flag client azzerati) oppure la elimina se Delete On Post After Import è attivo;
- se Post On After Data Import è attivo, Business Central pubblica il business event OnPostAfterImport sul record importato, per innescare elaborazioni custom (es. registrazione di un documento).
Le righe esterne prive di externalId valido vengono ignorate: l'import richiede i campi di sincronizzazione.
4.4 Buffer di sincronizzazione
Cerca Synchronize Buffer List per monitorare la coda. Ogni riga collega un record BC (System ID, con drill-down al record) alla sua identità esterna (External ID) e porta un Action Type:

| Action Type | Significato |
|---|---|
| Insert / Modify / Delete / Truncate | Operazione in attesa di esecuzione sul database esterno. |
| Skip | Già eseguita. La riga resta come registro: mappa System ID <-> External ID e dice all'app che il record è già stato esportato. |
| Bulk in Progress | Riga di un'interfaccia bulk in accodamento sulla testata. |
Dopo l'esecuzione, le righe Insert/Modify/Truncate passano a Skip; le righe Delete vengono rimosse dal buffer. L'azione Export query scarica la SQL della riga selezionata, utile per capire esattamente cosa verrà eseguito.
Non svuotare il buffer a mano: le righe Skip sono la memoria di ciò che è già stato esportato.
4.5 Web API
L'app espone le pagine API che i servizi consumano (gruppo api/applibra/bridge/v2.0): nodi, interfacce, buffer e Node Group (NAS). Non serve altra configurazione in Business Central oltre all'utente per i servizi.
5. Log e monitoraggio
- Node Interface Log: gli errori riportati dai servizi (connessione, SQL), per nodo e per interfaccia. È visibile in fondo alla scheda nodo e, a interfaccia abilitata, in fondo alla Node Interface Card, dal più recente.
- Synchronize SQL Log: con Log SQL attivo sull'interfaccia, ogni query accodata viene registrata con data/ora e contenuto SQL. Usalo in modo mirato per il debug: cresce rapidamente.
- Synchronize Buffer List: la coda in tempo reale (sezione 4.4).
6. Suggerimenti e risoluzione problemi
- Ho cambiato la password del nodo ma il servizio non si connette. Il servizio legge le credenziali all'inizio del ciclo di lavoro e le tiene in cache fino al riavvio o alla fine del ciclo (Restart Interval del Node Group). Riavvia il servizio dal License Manager, o attendi il ciclo successivo.
- L'interfaccia non si abilita. Con SQL Status = New l'abilitazione è bloccata: imposta Create Interface e lascia che il servizio crei la tabella esterna (SQL Status = Created) - vedi 3.7.
- I record non arrivano al database esterno. Verifica in ordine: Status del nodo = Enable; Status dell'interfaccia = Enable; Export to DB attivo; flag del Table Setup attivi per la tabella; il Node Group del nodo è quello configurato nel servizio (un servizio lavora solo il proprio gruppo); righe nel buffer con Status = Enable; Node Interface Log per errori SQL.
- SQL Status fermo su Create Interface. Il servizio non gira, serve un altro Node Group, o la connessione/DDL fallisce: controlla il Node Interface Log e il log del servizio nel License Manager.
- Le query manuali su PostgreSQL non trovano la tabella o i campi. Gli identificatori sono creati quotati e quindi case-sensitive:
SELECT * FROM "Customer"non èselect * from customer. Meglio ricreare l'interfaccia con nomi minuscoli (vedi 3.6). - Modifiche non intercettate da una sessione aperta da prima. La configurazione dei trigger è letta all'apertura della società: fai riaprire le sessioni dopo aver aggiunto tabelle nuove.
- Select rows with NOLOCK non compare. È disponibile solo su nodi Microsoft SQL; PostgreSQL non lo supporta.
7. Supporto e risorse
- Editore: AppLibra
- Sito web: https://applibra.com
- Catalogo app: https://applibra.com/apps
- Informativa privacy: https://applibra.com/privacy-policy
- Condizioni d'uso: https://applibra.com/terms