[SOLVED] SQLite3 REINDEX lazarus / 16-Databases ---------------------------------------------------------------------- 1HuntnMan · 2025-04-11 20:08 Anyone know the correct syntax for REINDEX a SQLite3 table. Check out the attached diagram... I have a maintenance form for reindexing tables in the DataBase and VACUUM the database. I'm using SQLite3DataSet with TDataSource. It doesn't like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     SQLite3DSCntks.Open;    REINDEX.DSCntks.CONTACTS; // Reindex Contacts table ---------------------------------------------------------------------- JanRoza · 2025-04-11 20:57 Why not do it via sql like: .active := false; .sql.text := 'REINDEX CONTACTS'; .execsql; .sql.text := 'SELECT * FROM CONTACTS'; .active := true; ---------------------------------------------------------------------- 1HuntnMan · 2025-04-12 20:31 Ok JanRoza, the form I designed for reindexing and vacuuming, I had just SQLite3DataSet's. Would this work? SQLite3DSCntks.ExecSQL('REINDEX CONTACTS'); Or, would I need to remove the SQLite3DataSets and replace with a TSQLQuery i.e. QryCntks.Open, QryCntks.SQL.Text:='REINDEX CONTACTS';, QryCntks.ExecSQL; ---------------------------------------------------------------------- JanRoza · 2025-04-12 21:30 Just drop a query on your form and name it qryTemp or whatever you like and perform the sql action mentioned on that query. No need to change anything on your datasource. ---------------------------------------------------------------------- 1HuntnMan · 2025-04-12 21:40 Okay, that's cool! ---------------------------------------------------------------------- CharlyTango · 2025-04-13 08:08 hm.... That's kind of DBF thinking. One of the big advantages (and sometimes obstacles) is that i do not have to care about RE-indexing a sql server (and SQLite behaves as such one) In contrast to DBF files, an SQLite has a lot of functions and intelligence to offer. What you are dealing with is a DBMS (database management system), which requires a different way of thinking and handling data. You pass a data request (SELECT ... FROM) to the DBMS and get a response. The DBMS itself decides on the best access path, you don't have to worry about that. Accordingly, you cannot usually decide which index the DBMS uses or not. The DBMS also takes care of updating the indices. A clean table design with cleverly selected indices helps the DBMS to respond with high performance. But this is a matter for the DBMS and the topic of table design and has nothing to do with the database frontend. This different way of thinking also has consequences, because when you fetch data from a DBMS, you practically never do it by loading an entire table into a grid. This would be the absolute exception, whereas it is more common to access a table by index when displaying DBF files. It is therefore also good programming practice to offer the user a good search option with the aim of actually only having a handful of data in the grid from which the user can then select. Only if errors actually occur would it be necessary to rebuild indices. In 35 years of programming, I have hardly done this more than 5 times, but then the problem was so big anyway that backups came into play ---------------------------------------------------------------------- 1HuntnMan · 2025-04-13 11:56 CharlyTango,      That's exactly what I'm doing is converting a working app from DBF to SQLite3!  In this app when it was a good working app for a lot of folks written with DBF tables, it's a Contacts Mgt. app that friends and friends intall on their Winder's computers because Winders doesn't come with a Contacts app like the iPhone, iPad and Mac. Not sure about the Mac but assume.  Anyway, I have a lot of issues reteaching my brain for SQL. Another issue I have and guess I'm going to just delete this one unit and move on... In dBase I always have a unit in my DBF apps dedicated to maintenance of the dBase tables, reindex and pack all tables.  Accordingly, from what you just taught me, not needed! A headache I've been dealing with trying to change code.  For example, Lazarus/SQLite3 doesn't like this in my MaintTables.pas unit: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TFrmRebldCntksDB.SpdBtnRebuildClick(Sender: TObject);{ Pack the Contacts, Categores, Countries and States tables.   Recreate all table indexes for all tables in the database. }begin  SpdBtnRebuild.Enabled:= False;  ForceDirectories('Data');  PrgresBarRebld.Step:= 5;  PrgresBarRebld.Position:= 5;  try // Contacts table maintenance start...    DbfCntks.Exclusive:= True;    DbfCntks.Open;    DbfCntks.PackTable; // Pack Contacts.dbf    PrgresBarRebld.Position:= 10;    DbfCntks.RegenerateIndexes; // Reindex Contacts.dbf    DbfCntks.Close;  finally    DbfCntks.Free;    PrgresBarRebld.Position:= 20;  end;  try // Categories table maintenance start...    DbfCategories.Exclusive:= True;    PrgresBarRebld.Position:= 40;    DbfCategories.Open;    DbfCategories.PackTable; // Pack Categories.dbf    DbfCategories.RegenerateIndexes; // Reindex Categories.dbf    DbfCategories.Close;  finally    DbfCategories.Free;    PrgresBarRebld.Position:= 50;  end;...My changes... for SQLite3procedure TFrmRebldCntksDB.SpdBtnRebuildClick(Sender: TObject);{ Pack the Contacts, Categores, Countries and States tables. Delete  and recreate all table indexes for all tables in the database. }begin  SpdBtnRebuild.Enabled:= False;  PrgresBarRebld.Step:= 5;  PrgresBarRebld.Position:= 5;  try // Contacts table maintenance start...    QryCntks.Open;    //SQLite3DSCntks.Open;    //Sqlite3DSCntks.SQL:= 'REINDEX CONTACTS';    //Sqlite3DSCntks.ExecSQL('REINDEX CONTACTS');    QryCntks.SQL.Text:= 'REINDEX CONTACTS';    QryCntks.ExecSQL;  // Reindex Contacts table  PrgresBarRebld.Position:= 10;    QryCntks.Close;  finally    PrgresBarRebld.Position:= 20;  end;Then later, and this code errors:  //SQLite3DSCntks.ExecSQL('VACUUM'); Also, having issues reprogramming to change or set a table to open with an index active so the DBGrid shows in a specific order. This compiles but errors when I run: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TFrmCntksMain.FormShow(Sender: TObject);begin  {SQLite3DSCntks.IndexFieldNames:= 'CONTACTS';  SQLite3DSCntks.Open;  SQLite3DSStates.IndexFieldNames:= 'STPROVCODES';  SQLite3DSStates.Open;  SQLite3DSCntries.IndexFieldNames:= 'COUNTRIES';  SQLite3DSCntries.Open;  SQLite3DSCategories.IndexFieldNames:= 'CATEGORIES';  SQLite3DSCategories.Open;}  DSStates.DataSet.FieldByName('STPROVCODE').DisplayWidth:= 2;  DSStates.DataSet.FieldByName('STPROVNAME').DisplayWidth:= 12;  DSCntries.DataSet.FieldByName('CODE').DisplayWidth:= 2;  DSCntries.DataSet.FieldByName('COUNTRY').DisplayWidth:= 10;  DSCategories.DataSet.FieldByName('CATID').DisplayWidth:= 2;  DSCategories.DataSet.FieldByName('CATEGORY').DisplayWidth:= 25;  Contacts table, index CONTACT is indexed by LASTNAME, FIRSTNAME, MI. I also have a ComboBxSelIndex so the user can change the sort order of the table, i.e. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TFrmCntksMain.FormCreate(Sender: TObject);begin  //-> Add items to the CmboBxSelIndex component  CmboBxSelIndex.Items.Clear;  CmboBxSelIndex.Items.Add('Name (L,F,M)');  CmboBxSelIndex.Items.Add('Company');  CmboBxSelIndex.Items.Add('Category');  CmboBxSelIndex.Items.Add('State/Province');  CmboBxSelIndex.Items.Add('Country');  CmboBxSelIndex.Items.Add('City, State, Country');end; procedure TFrmCntksMain.CmboBxSelIndexSelect(Sender: TObject);begin  Case CmboBxSelIndex.Text of    'Name (L,F,M)':SQLite3DSCntks.IndexFieldNames:= 'CNTKLNAME';    'Company':SQLite3DSCntks.IndexFieldNames:= 'CLIENT';    'Category':SQLite3DSCntks.IndexFieldNames:= 'CATEGORY';    'State/Province':SQLite3DSCntks.IndexFieldNames:= 'STPROV';    'Country':SQLite3DSCntks.IndexFieldNames:= 'CNTRYCODE';    'City/Town':SQLite3DSCntks.IndexFieldNames:= 'CITYSTCNTRY'  else    WriteLn ('Index Unchanged!');  end;  JvDBSrchEditByIndex.DataField:= '';  SQLite3DSCntks.Refresh;end; I don't think this is going to work, not sure until I am able to figure out how to set the tables' active index. Tks... working on it! ---------------------------------------------------------------------- 1HuntnMan · 2025-04-13 20:20 Rewrote everything and no compile errors but when I attempt to run, Lazarus runs into an error at the 2nd line of the FormShow in the Main unit at the second line: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   SQLite3DSCntks.FileName:= SysUtils.ExtractFilePath(ParamStr(0))+'ContactsDB.SQLite3'  SQLite3DSCntks.Active:= True; // Error here: cntksmain.pas(227,3) Error: Syntax error, ";" expected but "identifier SQLITE3DSCNTKS" found ---------------------------------------------------------------------- cdbc · 2025-04-13 20:31 Missing ; (semicolon) in line 1 at the end. Regards ---------------------------------------------------------------------- 1HuntnMan · 2025-04-14 12:13 OMG      Tks, CDBC ---------------------------------------------------------------------- CharlyTango · 2025-04-18 09:02 Even if the analogy doesn't quite apply, a simplified model might help. If you use a DBMS such as SQLite, you can see the database as a black box from the application's point of view. The application is basically not responsible for data storage, optimisation, indexing or any other administrative tasks relating to the data. You can retrieve data from this black box using the SELECT commands. The DBMS is usually also responsible for sorting the required data. You get the data the way you want it. That's it. However, you can not only query a single table but also design the query in such a way that several tables are combined. For example, you can get the name, address and telephone number of several people in one query. For example, the user enters a location in the search window and receives a list of people with address and telephone number. You can query many things at the same time, but you can only write one table at a time. So there is no active index that can be set, only a desired sorting that you want to have in the query result. The DBMS decides which index (or several or even a full table scan) to use with the help of its query optimiser. The application has no influence on this. You can create intelligent indices in the DBMS, but the optimiser decides on their use. You no longer have anything to do with all the indices and switching between them. You only request the desired sorting. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i SELECT FROM ORDER BY If you want a different sorting, request a new result set from the DBMS with a new SELECT. This is normally so fast that the new query is not a problem. I practically always do it this way. ---------------------------------------------------------------------- CharlyTango · 2025-04-18 09:11 The part of the code that takes care of maintaining the tables and indices is unnecessary when using SQLite. Especially if you do this kind of data maintenance at every start. You can remove this from the start procedure and place it in a separate menu item if you wish. That takes care of this problem. ---------------------------------------------------------------------- CharlyTango · 2025-04-18 10:22 Set-based vs. row-based: An SQL database works at the level of sets, while a DBF database works at the level of rows. You need to get used to the new way of processing data. Join: In an SQL database, you can combine data from different tables by using join commands.