HlqMySQL, executes a query on a MySQL server

Home / Knowledge Base / Manualistica / Programmazione IEC 61131-3 / Server Harlequin / HlqMySQL, executes a query on a MySQL server

Questo blocco funzione permette di eseguire query su di un server MySQL tramite il server Harlequin, la gestione è delegata al FB HlqCommand di cui occorre fornire l'indirizzo dell'istanza nel parametro HlqC. Il FB si connette al server MySQL definito in Host connettendosi alla porta definita in Port, in User e Psw definire le credenziali di accesso. in Database definire il database su cui eseguire le query.

Attivando l'ingresso Enable viene eseguita la query definita in Query, se esecuzione  corretta si attiva l'uscita RxOk ed in ARows è ritornato il numero di righe modificate nel database ed in RRows il numero di righe ritornate in risposta. Il programma utente può acquisire la risposta dal buffer definito in Answer ed attivare per un loop RxAck che disattiva tutte le uscite e disalloca il buffer di risposta.

Terminata l'esecuzione si attiverà l'uscita Done che rimane attiva sino alla disabilitazione di Enable.  In TExecution è ritornato il tempo totale di esecuzione comando.

In caso di errore esecuzione viene attivata per un loop di programma l'uscita Fault. L'uscita Done si attiva al termine della esecuzione della richiesta e su errore. Per eseguire un'altro comando occorre disabilitare e poi riabilitare l'ingresso Enable.

Function block
CODESYS: Non disponibile
LogicLab: eLLabHarlequinLib

Enable (BOOL) Comando invio richiesta esecuzione. Per eseguire una nuova richiesta occorre disattivare e riattivare l'ingresso.

SpyOn (BOOL) Se attivo permette di spiare il funzionamento del FB (Vedi articolo).

RxAck (BOOL) Acnowledge risposta ricevuta, settare dopo avere acquisito la risposta.

HlqC (@HlqCommand) Indirizzo allocazione istanza FB HlqCommand di gestione comando.

Host (@STRING) Indirizzo IP o URL del server MySQL.

Port (UINT) Definizione porta da utilizzare su server MySQL (Default 3306).

User (@STRING) Definizione nome utente per autenticazione sul server MySQL.

Psw (@STRING) Definizione password per autenticazione sul server MySQL.

Database (@STRING) Definizione database su cui operare.

Query (@STRING) Definizione query da eseguire sul database.

LifeTime (REAL) Tempo di vita connessione al server MySQL in secondi, se non si eseguono queries nel tempo indicato viene considerata chiusa la connessione al server, alla prossima query verrà eseguita una nuova connessione. Valore massimo impostabile 3600 Secondi.

Done (BOOL) Attivo a fine esecuzione, si attiva anche in caso di Fault. L'uscita rimane attiva fino a quando non viene settato Enable:=FALSE.

Fault (BOOL) Attivo per un loop di programma se errore gestione.

RxOk (BOOL) Attivo alla ricezione della risposta dal server, rimane attivo sino al set di RxAck da parte del programma utente.

ALength (UDINT) Lunghezza stringa risposta ricevuta. Rimane valido sino alla disabilitazione.

Answer (@STRING) Valorizzato su ricezione risposta, ritorna indirizzo allocazione messaggio ricevuto. Rimane valido fino all'acknowledge della risposta (Attivazione RxAck) da parte del programma.

TExecution (REAL) Tempo esecuzione comando, da invio richiesta a ricezione risposta (S).

Queries (UDINT) Ritorna il numero di interrogazioni eseguite correttamente.

Errors (UDINT) Ritorna il numero di esecuzioni terminate per errore.

Spionaggio funzionamento

Se SpyOn attivo è possibile utilizzare utilizzare la console di spionaggio per verificare il funzionamento della FB. Sono previsti vari livelli di triggers.

Errori

In caso di errore si attiva l'uscita Fault, con la funzione SysGetLastError è possibile rilevare il codice di errore. Fare riferimento alla tabella seguente per la descrizione.

Esempi

Come utilizzare gli esempi.
Attivando da debug la variabile Send viene inviata la query di UPDATE del valore di una tabella, nell'esempio riporto anche una query di INSERT di un record in tabella. Eseguita la query di UPDATE viene eseguita una query di SELECT che ritorna il valore di cui si è eseguito l'update e viene controllato se il valore corrisponde. Per utilizzare l'esempio bisogna modificare i valori definendo quelli del server MySQL che si utilizza.

LogicLab (Ptp180)
PROGRAM ST_HlqMySQL
VAR
    Send : BOOL; (* Query send *)
    i : UDINT; (* Auxiliary variable *)
    CaseNr : USINT; (* Case programma *)
    QSize : UINT := 1024; (* SQL query size *)
    HlqC : HlqCommand; (* Harlequin command *)
    HlqMySQL : HlqMySQL; (* Harlequin MySQL *)
    Counter : ARRAY[0..1] OF UDINT; (* Counter variable *)
    Errors : UDINT; (* Error counter *)
    JDecode : JSONDecode_v2; (* JSON decode *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_HlqMySQL"
// *****************************************************************************
// This example shows how to use the FB to execute queries.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // INITIALIZATIONS
    // -------------------------------------------------------------------------
    // FB initializations.

    IF (SysFirstLoop) THEN

        // Harlequin command settings.

        HlqC.SpyOn:=TRUE; //Spy on
        HlqC.AChunked:=FALSE; //Answer chunked
        HlqC.SAddress:=ADR('127.0.0.1'); //Server address
        HlqC.SPort:=8101; //Server port
        HlqC.Delay:=0.5; //Command delay (S)
        HlqC.Timeout:=10.0; //Execution timeout (S)

        // Harlequin MySQL settings.

        HlqMySQL.SpyOn:=TRUE; //Spy on
        HlqMySQL.HlqC:=ADR(HlqC); //Harlequin command

        // MySQL server settings.

        HlqMySQL.Host:=ADR('192.168.1.10'); //MySQL Host
        HlqMySQL.Port:=3306; //MySQL port
        HlqMySQL.User:=ADR('user'); //Username
        HlqMySQL.Psw:=ADR('password'); //Password
        HlqMySQL.Database:=ADR('database'); //Database
        HlqMySQL.LifeTime:=10.0; //Life time (S)
    END_IF;

    // -------------------------------------------------------------------------
    // FB MANAGER
    // -------------------------------------------------------------------------
    // Manage the FB and check if is in fault.

    HlqMySQL(); //Harlequin MySQL
    HlqMySQL.RxAck:=FALSE; //Answer Rx acknowledge
    IF (HlqMySQL.Fault) THEN CaseNr:=0; END_IF;

    // -------------------------------------------------------------------------
    // EXECUTION CASE
    // -------------------------------------------------------------------------
    // Execution case manager.

    CASE (CaseNr) OF

        // ---------------------------------------------------------------------
        // Waits if the "Send" command has been set by debug..

        0:
        HlqMySQL.Enable:=FALSE; //Enable
        HlqMySQL.RxAck:=FALSE; //Answer Rx acknowledge
        IF (HlqMySQL.Query <> NULL) THEN i:=SysRMFree(ADR(HlqMySQL.Query)); END_IF;
        IF NOT(Send) THEN RETURN; END_IF;

        // Allocate the buffer to contains the eMail text.

        IF NOT(SysRMAlloc(QSize, ADR(HlqMySQL.Query))) THEN RETURN; END_IF;
        Counter[0]:=Counter[0]+1;
        Send:=FALSE; //EMail send
        CaseNr:=CaseNr+1; //Case programma

        // ---------------------------------------------------------------------
        // UPDATE OR INSERT QUERY
        // ---------------------------------------------------------------------
        // Compile the query.

        1:
        // i:=SysVsnprintf(HlqMySQL.Query, QSize, ADR('INSERT INTO Table (Name, Value) VALUES ("Counter", %d)'), UDINT_TYPE, ADR(Counter[0]));
        i:=SysVsnprintf(HlqMySQL.Query, QSize, ADR('UPDATE Table SET Value=%d WHERE ID=1'), UDINT_TYPE, ADR(Counter[0]));
        HlqMySQL.Enable:=TRUE; //Enable
        HlqMySQL.RxAck:=TRUE; //Answer Rx acknowledge
        IF NOT(HlqMySQL.Done) THEN RETURN; END_IF;
        HlqMySQL.Enable:=FALSE; //Enable

        // Check if a rows has been affected.

        IF (HlqMySQL.ARows <> 1) THEN Errors:=Errors+1; CaseNr:=0; RETURN; END_IF;
        CaseNr:=CaseNr+1; //Case programma

        // ---------------------------------------------------------------------
        // SELECT QUERY
        // ---------------------------------------------------------------------
        // Compile the query.

        2:
        i:=SysVsnprintf(HlqMySQL.Query, QSize, ADR('%s'), STRING_TYPE, ADR('SELECT * FROM Table LIMIT 1'));

        // Waits for the answer it will be:
        // {"ID":1,"Name":"Name","Value":27}

        HlqMySQL.Enable:=TRUE; //Enable
        IF (HlqMySQL.RxOk) THEN
            HlqMySQL.RxAck:=TRUE; //Answer Rx acknowledge

            IF (HlqMySQL.RRows <> 1) THEN Errors:=Errors+1; CaseNr:=0; RETURN; END_IF;    
            JDecode(Object:=HlqMySQL.Answer, Name:=ADR('Value'), VType:=UDINT_TYPE, VAddress:=ADR(Counter[1]), Count:=1);
            IF (JDecode.ECode <> 0) THEN Errors:=Errors+1; CaseNr:=0; RETURN; END_IF;
            IF (Counter[0] <> Counter[1]) THEN Errors:=Errors+1; CaseNr:=0; RETURN; END_IF;
        END_IF;

        // Waits for query executed.

        IF NOT(HlqMySQL.Done) THEN RETURN; END_IF;
        HlqMySQL.Enable:=FALSE; //Enable
        CaseNr:=0; //Case programma
    END_CASE;

// [End of file]

Ti è stato utile questo articolo ?