Autor Téma: SQLite Update nefunguje  (Přečteno 4104 krát)

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 450
  • Karma: 16
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
SQLite Update nefunguje
« kdy: 18-03-2018, 00:04:45 »
Nejde mi Update. Presnejšie jeho výsledky sa nijako neprejavia.
Ido o dva SQL príkazy. Jedno Select, druhé Update. To prvé riadi napĺňanie druhého.
Select je JOIN dvoch tabuliek. Za zmienku stojí, že Update sa týka jednej z tabuliek použitých v  Select.
Asi bude problém s nejakým Lock.. Zrejme parametre conn, alebo query.. Všetko sa zdá na prvý pohľad v poriadku. Debugovanie ukazuje správne naplnené hodnoty parametrov pre update.
Nehlási sa žiadna chyba. V ramci Try ani neprebehne cez oblasť EXCEPT.. takže bez chyby.. Lenže hodnoty v tabuľke sa nezmenia!!! Princíp :
Kód: Delphi [Vybrat]
  1. try
  2.   conn.StartTransaction;
  3.   ..  // Update kód ja nižšie
  4.   conn.commit
  5. except
  6.   conn.rollback
  7.   end
Viac info:
Kód: Delphi [Vybrat]
  1.     qU                  := TFDQuery.Create( self );
  2.     qU.Connection       := conn;
  3.     qS                  := TFDQuery.Create( self );
  4.     qS.Connection       := conn;
  5.     qU.SQL.Text         := 'UPDATE Csv SET Flag=? WHERE rowid= ?' );
  6.     qU.Params.BindMode  := pbByNumber;
  7. ..
  8.     qu.Params.ArraySize := kMaxArrSize;  // 10 000
  9.     qS.SQL.Text         := sSQL; // Transactions and DML Commands, odkaz dolu
  10.     qS.Active           := TRUE;
  11.     qS.DisableControls;
  12.     j                   := 0;
  13.     qs.First;
  14.     while not qs.eof do
  15.       begin
  16.       for i := 0 to qS.FieldCount - 1 do
  17.         begin
  18.         if qs.fields[ i ].IsNull then
  19.           qU.Params[ i ].Clear( j )
  20.         else
  21.           qU.Params[ i ].Values[ j ] := qs.fields[ i ].Value;
  22.         end;
  23.       qs.Next;
  24.       Inc( j );
  25.       if j = kMaxArrSize then  
  26.         begin
  27.         conn.StartTransaction;
  28.         try
  29.           qu.Execute( j );        // 10 000 update naraz
  30.           j := 0;
  31.           conn.Commit;
  32.         except
  33.           conn.Rollback;
  34.           end;
  35.         end;
  36.       end;
  37.     qs.EnableControls;
  38. ..
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_SQLite_with_FireDAC#SQLite_Transactions.2C_Locking.2C_Threads_and_Cursors

Neviete poradiť prečo, sa hodnoty neprejavia? Aj napriek tomu, že všetko prebehne presne tak, ako by malo ? Bez chyby, len tie data nereagujú..

Select:
Kód: MySQL [Vybrat]
  1. SELECT d.[Flag] | 16, d.rowid        
  2.    FROM Csv AS d
  3.         INNER JOIN
  4.         KonZast k
  5.           ON d.[CISLO ZASTAVKY]=k.[CISLO ZASTAVKY]
  6.    ORDER BY D.ROWID
« Poslední změna: 18-03-2018, 00:31:27 od Miroslav Baláž »

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4223
  • Karma: 37
    • Verze Delphi: XE7 professional
Re:SQLite Update nefunguje
« Odpověď #1 kdy: 18-03-2018, 10:11:36 »
Ja tam vidím 2 x conn.StartTransaction; To je chyba! To máš dve samostatné transakcie.
Kód: Delphi [Vybrat]
  1. if j = kMaxArrSize then  
  2. begin
  3.     conn.StartTransaction;
  4.  
  5.      try
  6.         qu.Execute( j );        // 10 000 update naraz
  7.         j := 0;
  8.         conn.Commit;
  9.     except
  10.         conn.Rollback;
  11.      end;
  12. end;
  13.  
Toto mi hlava neberie. Čo sa stane, vzhľadom na prvú ukážku kódu, ak budeš mať viac ako 10 000 požiadaviek? Urob si pre update samostatnú transakciu a obsluhuj ju len v kóde hore.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 450
  • Karma: 16
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite Update nefunguje
« Odpověď #2 kdy: 18-03-2018, 10:36:50 »
Ja tam vidím 2 x conn.StartTransaction; To je chyba! To máš dve samostatné transakcie.
Mozno je na tom nieco, ale neslo to, ani ked to bolo cele zabalene do jednej transakcie, vratane vodiaceho select query (qS). Chyba bude zrejme v nastaveniach Conn a qS, ci qU. Ale tych nastaveni je milion .., tak neviem identifikovat tie spravne.
Mnohe veci v podobnom kontexte idu.

Toto mi hlava neberie. Čo sa stane, vzhľadom na prvú ukážku kódu, ak budeš mať viac ako 10 000 požiadaviek? Urob si pre update samostatnú transakciu a obsluhuj ju len v kóde hore.
To je Array DML. Vid odkaz:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_SQLite_with_FireDAC#SQLite_Transactions.2C_Locking.2C_Threads_and_Cursors
Cyklus okolo j je dobre. Je to zabalene v not qs.EOF .. qs.next. J-cko sa vzdy po 10 000-coch resetuje na 0. V ramci vodiaceho qS, prebehne cca 3 miliony x Update. Teda v davkach po 10 000. Oproti jednotlivym zapisom je to vyznamne zrychlenie. Bez array DML je to zufalo pomale, pre dane potreby.
Ale je fakt, ze som to skusal aj bez Array DML ale Update sa tiez nijako neprejavil. Prosim, ak mate niekto info k potrebnym nastaveniam conn, qS, qU, ci lock, ci wait, alebo ..,  pre dany pripad, budem vdacny za radu.
« Poslední změna: 18-03-2018, 10:47:03 od Miroslav Baláž »

Offline Delfin

  • Padawan
  • ******
  • Příspěvků: 1759
  • Karma: 68
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:SQLite Update nefunguje
« Odpověď #3 kdy: 18-03-2018, 10:58:00 »
Oproti jednotlivym zapisom je to vyznamne zrychlenie. Array DML

Array DML je v tomto pripade jen emulovan. A obecne ma vyznam pro prenos dat do RDBMD po siti. SQLite podporuje jen INSERT vicenasobnych hodnot. Takze ve Tvem pripade dojde stejne interne jen k opakovanemu spousteni dotazu.

Co vsak myslis tim projevem hodnot? Letmo vsak (cimz netvrdim ze je to duvod pro chybejici commit zmen), tu transakci bys mel ovladat pro celou davku, ne pro kazdy spousteny Execute (abys zachoval konzistenci dat).
« Poslední změna: 18-03-2018, 11:02:57 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4223
  • Karma: 37
    • Verze Delphi: XE7 professional
Re:SQLite Update nefunguje
« Odpověď #4 kdy: 18-03-2018, 11:03:49 »
Zopakujem: vytvor si samostatné TRANSACTION pre qS a qU. Pre qS Autocommit True, pre qU False. Teraz sa Ti bijú. Array DML používam a nemám problém.
Kód: Delphi [Vybrat]
  1.   conFOC := TFDConnection.Create(Self);
  2.   conFOC.Connected := False;
  3.   conFOC.DriverName := 'FB';
  4.   conFOC.Params.DriverID := 'FB';
  5.  
  6.  
  7.   trnTblRead := TFDTransaction.Create(Self);
  8.   trnTblRead.Connection := conFOC;
  9.   trnTblRead.Options.Isolation := xiReadCommitted;
  10.   trnTblRead.Options.AutoStart := True;
  11.   trnTblRead.Options.AutoCommit := True;
  12.   trnTblRead.Options.ReadOnly := True;
  13.   trnTblRead.Options.DisconnectAction := xdRollback;
  14.  
  15.  
  16.   trnQrySelect := TFDTransaction.Create(Self);
  17.   trnQrySelect.Connection := conFOC;
  18.   trnQrySelect.Options.Isolation := xiReadCommitted;
  19.   trnQrySelect.Options.AutoStart := True;
  20.   trnQrySelect.Options.AutoCommit := True;
  21.   trnQrySelect.Options.ReadOnly := True;
  22.   trnQrySelect.Options.DisconnectAction := xdRollback;
  23.  
  24.  
  25.   trnUpd := TFDTransaction.Create(Self);
  26.   trnUpd.Connection := conFOC;
  27.   trnUpd.Options.Isolation := xiReadCommitted;
  28.   trnUpd.Options.AutoStart := False;
  29.   trnUpd.Options.AutoCommit := False;
  30.   trnUpd.Options.ReadOnly := False;
  31.   trnUpd.Options.DisconnectAction := xdRollback;
  32.  
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Delfin

  • Padawan
  • ******
  • Příspěvků: 1759
  • Karma: 68
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:SQLite Update nefunguje
« Odpověď #5 kdy: 18-03-2018, 11:18:23 »
Zopakujem: vytvor si samostatné TRANSACTION pre qS a qU. Pre qS Autocommit True, pre qU False. Teraz sa Ti bijú.

Porad nevidim problem, i kdyby slo o pouziti Nested Transactions.
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 4223
  • Karma: 37
    • Verze Delphi: XE7 professional
Re:SQLite Update nefunguje
« Odpověď #6 kdy: 18-03-2018, 11:19:41 »
Dodatok: Ak vykonáš Commit, tak sa transakcia automaticky ukončí. Tým pádom má aj qS ukončenú transakciu. Čo to pre neho v praxi znamená netuším. Narážam na to či si naďalej drží svoj obsah - dataset.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Online pf1957

  • Padawan
  • ******
  • Příspěvků: 2525
  • Karma: 131
    • Verze Delphi: D2007, XE3, DX10
Re:SQLite Update nefunguje
« Odpověď #7 kdy: 18-03-2018, 11:27:48 »
Zopakujem: vytvor si samostatné TRANSACTION pre qS a qU.
Nedavno jsem vice transakci pres FireDAC resil s kolegou, kdyz migroval SW z FB na MSSQL, protoze se mu to chovalo divne (a to je eufemismus).

Vice transakci funguje jen na Interbase/FireBirdu... Podivej se na odstavec Multiple Active Transactions tady http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Managing_Transactions_(FireDAC) a nenapadnou poznamku pod fragmentem kodu.

Offline Delfin

  • Padawan
  • ******
  • Příspěvků: 1759
  • Karma: 68
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:SQLite Update nefunguje
« Odpověď #8 kdy: 18-03-2018, 13:56:57 »
Zopakujem: vytvor si samostatné TRANSACTION pre qS a qU.
Nedavno jsem vice transakci pres FireDAC resil s kolegou, kdyz migroval SW z FB na MSSQL, protoze se mu to chovalo divne (a to je eufemismus).

Vice transakci funguje jen na Interbase/FireBirdu... Podivej se na odstavec Multiple Active Transactions tady http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Managing_Transactions_(FireDAC) a nenapadnou poznamku pod fragmentem kodu.

Co konkretne? Mozna bych poradil, ale prosim o MCVE a separatni vlakno. Stejne tak by MCVE pomohlo tady u tohoto vlakna.
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Online pf1957

  • Padawan
  • ******
  • Příspěvků: 2525
  • Karma: 131
    • Verze Delphi: D2007, XE3, DX10
Re:SQLite Update nefunguje
« Odpověď #9 kdy: 18-03-2018, 13:59:30 »
Co konkretne? Mozna bych poradil, ale prosim o MCVE a separatni vlakno. Stejne tak by MCVE pomohlo tady u tohoto vlakna.
Neni co resit - proste FireDAC pouziva jen jednu aktivni transakci, pokud neni RDBMS Firebird.

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 450
  • Karma: 16
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite Update nefunguje
« Odpověď #10 kdy: 18-03-2018, 14:45:37 »
Oproti jednotlivym zapisom je to vyznamne zrychlenie. Array DML
Array DML je v tomto pripade jen emulovan. A obecne ma vyznam pro prenos dat do RDBMD po siti. SQLite podporuje jen INSERT vicenasobnych hodnot. Takze ve Tvem pripade dojde stejne interne jen k opakovanemu spousteni dotazu.
Ano, na danej stranke je napisane, ze primarne sa to riesi nejakou technikou SQLite, ktora je dostupna od v. 3.7.x. Ak nie je dostupna, emuluje sa Array DML. FireDAC aktualne pouziva SQLite v. 3.9.X
Oproti jednotlivym zapisom je to vyznamne zrychlenie. Array DML
Co vsak myslis tim projevem hodnot? Letmo vsak (cimz netvrdim ze je to duvod pro chybejici commit zmen), tu transakci bys mel ovladat pro celou davku, ne pro kazdy spousteny Execute (abys zachoval konzistenci dat).
Debugoval som data. Ide vlastne o bitovu operaciu OR. Napriklad povodna hodnota 4   |   8 ako pridana. Pri debugovani ziskam cislo 12, to sa aj ulozi do prveho parametra qU (vidim ho v debugeri tiez ako 12). Druhy parameter je rowid, ten je tiez v poriadku. (skontrolovane). Lenze po skonceni sa v datach stale vyskytuje povodna 4-ka pre dany rowid.
Teda nie to, co bolo vlozene do qU parametra, ale povodna hodnota.
Pri debugovani to vyzera idealne. Lenze UPDATE sa vykona len ako placebo efekt, nie naozaj. Pritom chyba nie je hlasena.
Transakcia, bola povodne nastavena na celu posobnost qS, qU. Chovanie sa nijako nezmenilo. Stale len PLACEBO efekt. A ani ziadna chybova hlaska. Alebo, ze by vnutri cyklov bezali zle udaje, naopak tie  vyzeraju presne, ako sa ocakavalo.
« Poslední změna: 18-03-2018, 15:03:43 od Miroslav Baláž »

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 450
  • Karma: 16
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite Update nefunguje
« Odpověď #11 kdy: 18-03-2018, 14:55:07 »
Doplnujuce info :
Takmer identicky Update, som uz riesil inde, pricom vyuzivam UDF funkciu, namiesto qS.
V nej nieco vypocitavam, posledny parameter funkcie mam ROWID a vdaka nemu do Csv tabulky zapisujem vypocitane udaje. Tam to funguje.
« Poslední změna: 18-03-2018, 15:05:02 od Miroslav Baláž »

Offline Delfin

  • Padawan
  • ******
  • Příspěvků: 1759
  • Karma: 68
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:SQLite Update nefunguje
« Odpověď #12 kdy: 18-03-2018, 15:14:08 »
Ano, na danej stranke je napisane, ze primarne sa to riesi nejakou technikou SQLite, ktora je dostupna od v. 3.7.x. Ak nie je dostupna, emuluje sa Array DML. FireDAC aktualne pouziva SQLite v. 3.9.X

Ano, jenze jen pro prikaz INSERT. A ani tam nejde o Array DML, ale INSERT s vicenasobnymi hodnotami.
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Online pf1957

  • Padawan
  • ******
  • Příspěvků: 2525
  • Karma: 131
    • Verze Delphi: D2007, XE3, DX10
Re:SQLite Update nefunguje
« Odpověď #13 kdy: 18-03-2018, 15:34:31 »
Pri debugovani to vyzera idealne. Lenze UPDATE sa vykona len ako placebo efekt, nie naozaj. Pritom chyba nie je hlasena.
Zadna hlaseni s tim vetsinou spojena nejsou a je treba testovat RowsAffected a ev. raisnout exception, pokud nesouhlasi. Tech chyb muze byt v podstate jen par 1) zadny radek pro update nesplnuje podminku ve where klauzuli 2) necommitnuta nebo odrolovana transakce 3) menis neco jineho nez si myslis

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 450
  • Karma: 16
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite Update nefunguje
« Odpověď #14 kdy: 18-03-2018, 15:54:48 »
V debugeri idem v cykle cez qS
Z nej preberam 2 hodnoty Flag a ROWID
Vidim napriklad rowid 17, je tam v CSV flag = 4, vdaka vyrazu v qS   "Flag | 8", ziskam qs.fields[0].AsInteger cislo 12.
Priradim
qU.params[0].AsInteger := 12   -- FLAG
qU.params[1].AsInteger := 17   -- ROWID
Parametre su naplnene ( vidim ich hodnoty v debugeri)
Uplatnim qU.ExecSQL
Pozriem vysledok a v riadku s rowid 17, je hodnota Flag stale 4.
Transaction, prebehne cez Commit, nie Rollback
Idem spravit kratky vzor projekt
« Poslední změna: 18-03-2018, 15:57:10 od Miroslav Baláž »