Italian Inserimento multirighe in DB sqlite remoto

Xela

Member
Licensed User
Longtime User
Buona serata a tutti (almeno a Voi)
E' una settimana che sto girando e rigirando il codice per riuscire ad inserire più righe in una tabella che si trova in un db sqlite remoto.

Partiamo dall'inizio. Devo:
1) ricavare il numero dell'ordine
2) inserire in una tabella una riga di testata ordine
3) inserire in un'altra tabella più righe di dettaglio.

Uso questa procedura:

Ricavo n. ordine da una tabella e aggiorno la stessa all'ordine successivo

B4X:
'Ricavo n. ordine precedente
Private Sub RDC_GetOrderNumber()
    Dim cmd As DBCommand
    cmd.Initialize
    cmd.Name = "Select_GetOrderNumber"
    reqManager.ExecuteQuery(cmd, 0, "Select_GetOrderNumber")
End Sub

'Aggiorno a n. ordine Attuale
Private Sub RDC_UpdateOrderNumber(OrderNumber As String)
    Dim cmd As DBCommand
    cmd.Initialize
    Dim Param(1) As Object
    Param(0) = OrderNumber
    cmd.Parameters = Param
    cmd.Name = "Update_OrderNumber"
    reqManager.ExecuteCommand(cmd, "Update_OrderNumber")
End Sub

Inserisco le righe di dettaglio e verifico che siano state inserite tutte ricavando l'importo totale

B4X:
'inserisco righe di dettaglio ricavate da una Map
Private Sub RDC_InsertOrderRow(OrderNumber As String)
    Dim i As Int
    Dim cmd As DBCommand
    cmd.Initialize
    For i = 0 To MapRowGrp.Size -1
        Dim sRowGrp As RowList
        sRowGrp = MapRowGrp.Get(i)
        Dim sDes As String
        sDes = sRowGrp.sDes.Trim
        sDes = sDes.Replace(",", "")
        sDes = sDes.Replace(".", "")
        nSumTotRowOut = nSumTotRowOut + sRowGrp.nTot
        cmd.Parameters = Array As Object(OrderNumber, sRowGrp.sCod, sDes, "", sRowGrp.nQta, sRowGrp.nPrzPie + sRowGrp.nPrzTY1 + sRowGrp.nPrzTY2, sRowGrp.nTot, sRowGrp.sPrint, "0", "", "", "", "0", sRowGrp.nProgre, sRowGrp.PrgPie, sRowGrp.PrgAgg)
        cmd.Name = "Insert_OrderRow"
        reqManager.ExecuteCommand(cmd, "Insert_OrderRow")
        x = i
    Next
End Sub

'se inserito ultima riga calcolo la somma
.....
Case "Insert_OrderRow"
    If x = MapRowGrp.Size -1 Then
        x = 0
        RDC_GetSumRowOrd(sNewNumOrd)
    End If
.....
Private Sub RDC_GetSumRowOrd(sOrd As String)
    Dim cmd As DBCommand
    cmd.Initialize
    cmd.Parameters = Array As Object(sOrd)
    cmd.Name = "Select_GetSumRowOrd"
    reqManager.ExecuteQuery(cmd, 0, "Select_GetSumRowOrd")
End Sub

'se somma coincide procedo con inserimento di testata dell'ordine

B4X:
....
Case "Select_GetSumRowOrd"
    Dim Record() As Object = result.Rows.Get(0)
    nSumTotRowDB = Record(0)
    If nSumTotRowOut <> nSumTotRowDB Then
        Log(nRaundTotRow & " / " & nSumTotRowOut & "-" & nSumTotRowDB)

        nRaundTotRow = nRaundTotRow + 1
        If nRaundTotRow < 10 Then
            Sleep(1000)
            RDC_GetSumRowOrd(sNewNumOrd)
        Else
            .......
        End If
    Else
        Log(nRaundTotRow & " / " & nSumTotRowOut & "-" & nSumTotRowDB)

        RDC_InsertOrderNew(sNewNumOrd, _
            mdoFunction.FormatDate(DateTime.Now,"yyyy-MM-dd"), _
            mdoFunction.FormatDate(DateTime.Now,"HH:mm:ss"), _
            Main.gName, _
            lblTotale.Text, _'.Replace(",","."), _
            "", _
            lblPlace.Text, _
            lblTable.text, _
            mdoFunction.FormatDate(DateTime.Now,"yyyy-MM-dd HH:mm:ss"), _
            "", _
            "", _
            "0", _
            "0", _
            "0", _
            "0", _
            "", _
            "0", _
            "0", _
            "0", _
            "1", _
            Main.gIPDevice, _
            "XSeO25", _
            "", _
            "", _
            Main.gIDAnag, _
            Main.gDateDelivery, _
            Main.gTimeDelivery, _
            Main.gPhone, _
            Main.gTown, _
            Main.gPayType)
    End If
....
'Inserisco Testata Ordine
Private Sub RDC_InsertOrderNew(OrderNumber As String, OrderData As String, OrderTime As String, Name As String, ImportoTotale As Double, CodReparto As String, Coperti As Int, NumeroTavolo As String, OraAssegnaTav As String, OraStatus As String, DesStatus As String, StampaUnita As String, Aggiunta As String, PrintedORD As String, PrintedFISC As String, SconFisc As String, Blocco As String, Personale As String, Sconto As String, SeatClosed As String, PCOrd As String, TipoOrdine As String, NomeFile As String, PCConferma As String, IDAnag As Int, DataConsegna As String, OraConsegna As String, NumeroTelefono As String, LottPIva As String, PayType As String)
    Dim cmd As DBCommand
    cmd.Initialize
    cmd.Parameters = Array As Object(OrderNumber, OrderData, OrderTime, Name, ImportoTotale, CodReparto, Coperti, NumeroTavolo, OraAssegnaTav, OraStatus, DesStatus, StampaUnita, Aggiunta, PrintedORD, PrintedFISC, SconFisc, Blocco, Personale, Sconto, SeatClosed, PCOrd, TipoOrdine, NomeFile, PCConferma, IDAnag, DataConsegna, OraConsegna, NumeroTelefono, LottPIva, PayType)
    cmd.Name = "Insert_OrderNew"
    reqManager.ExecuteCommand(cmd, "Insert_OrderNew")
End Sub

Verifico che la riga dell'ordine sia stata inserita

B4X:
Private Sub RDC_GetSumOrd(sOrd As String)
    Dim cmd As DBCommand
    cmd.Initialize
    cmd.Parameters = Array As Object(sOrd)
    cmd.Name = "Select_GetSumOrd"
    reqManager.ExecuteQuery(cmd, 0, "Select_GetSumOrd")
End Sub

Bene. Sembra fatto.
Invece no. Riscontro problemi nell'inserimento delle righe di dettaglio
Riscontro diversi problemi.
Se provo con app in debug e jrdc2 in debug tutto funziona anche se le righe di dettaglio non vengono inserite nell'ordine in qui sono state inviate.
Se provo con app in release e jrdc2 in debug il 20% delle volte mi si pianta nell'inserimento delle righe di dettaglio
Se provo con app in debug e jrdc2 in release mi si pianta nell'inserimento delle righe di dettaglio
Idem con app in release.

C'è qualcuno cosi gentile da consigliarmi qualche soluzione?

Grazie
 

udg

Expert
Licensed User
Longtime User
Non utilizzo RDC/RDC2 quindi non posso entrare nel merito del problema. Però vorrei evidenziare una situazione che mi sembra "pericolosa".
Cosa succede se tra la lettura del codice ordine e il suo aggiornamento da parte del client1, la stessa operazione viene eseguita dal client2 (più rapido per mille motivi)?
In genere queste operazioni dovrebbero essere "atomiche" (leggo, incremento, salvo) o prevedere un lock della tabella in modo che altri processi debbano attendere.
 

LucaMs

Expert
Licensed User
Longtime User
Usa Wait For quando invii un comando.

B4X:
Sub InsertRecord (Name As String)
   Dim cmd As DBCommand = CreateCommand("insert_animal", Array(Name, Null))
   Dim j As HttpJob = CreateRequest.ExecuteBatch(Array(cmd), Null)
   Wait For(j) JobDone(j As HttpJob)
   If j.Success Then
       Log("Inserted successfully!")
   End If
   j.Release
End Sub
 

Xela

Member
Licensed User
Longtime User
Grazie per la segnalazione. Sono al corrente del rischio.
Purtroppo in B4X non so come fare e jrdc2 credo non mi da questa opportunità. Per questo leggo poi incremento e salvo se coincidono e poi controllo. se c'è discordanza riparto. non è proprio una procedura pulita ma......
Comunque qualsiasi tua indicazione sarà certamente utile.
Grazie ancora
 

udg

Expert
Licensed User
Longtime User
Per un DB MySql/MariaDB avevo scritto una store procedure che in un'unica chiamata eseguiva le 3 operazioni (leggo, incremento,scrivo) in un colpo solo.
Se non ricordo male il lock della tabella avveniva in automatico (oppure lo inserivo io nel codice della procedure, non ricordo)
Non sono sicuro di averne una copia perché è roba molto datata, ma se dovesse saltare fuori qualcosa di utile lo aggiumgerei a questo thread.
 

Xela

Member
Licensed User
Longtime User
Grazie
Ci conto.
 

Xela

Member
Licensed User
Longtime User
E di questa... 'sti cazzi!

Ciao.
un attimo arrivo anche da te.......
la sto provando.

comunque mi rimane sempre una domanda:
ma non dovrebbe essere il dbrequestmanager a gestire sta cosa?
o serve sole per le select?

comunque grazie per l'indicazione.

torno dopo quando ho testato
 

Xela

Member
Licensed User
Longtime User

Con questa soluzione funziona anche con il jrdc2 in release e mantiene l'ordine di inserimento

grazie
 

Xfood

Expert
Licensed User
Potresti semplicemente aggiungere un campo lock/bloccato, quando decidi di modificare un ordine lo metti a true, fainle modifiche evalla fine lonrimettiba false, se un altro client accede verifica il campo se true attende e non fa nulla, se false il client2 lo mette a true e fa le sue operazioni, che poi alla fine rimette a false, e cosi via.
 

Xela

Member
Licensed User
Longtime User
buona idea
ci lavoro
Grazie 1000
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…