Zeoslib won't allow switching database? - database

I use Zeoslib components to interact with my SQLite database file. I have several SQLite database files in a folder. So, I want to be able to open any one of them using Zeoslib component. However, it won't let me. It opens the first database successfully but any database file I open after that, I get access violation error. For the life of me, I simply can't figure it out WHY.
Here is how I open database file.
procedure TMainFrm.Open1Click(Sender: TObject);
var currdb:string;
begin
OpenDlg.InitialDir := BaseDir;
if OpenDlg.Execute = true then
begin
currdb := Extractfilename(OpenDlg.FileName);
DataModule1.ZConnection1.Disconnect;
DataModule1.ZConnection1.Protocol := 'SQLite-3';
DataModule1.ZConnection1.Database :=baseDir + currdb;
DataModule1.Query1.SQL.Clear;
DataModule1.Query1.SQL.Add('SELECT * FROM MyTable'); // <<<<--- ZConnection1 is Query1 database connection.
DataModule1.ZConnection1.Connect; // <<<<<-------Here is where I get ACCESS VIOLATION all the time.
UpdateGrid; // <<<<<<<----- Here is where the Query is executed and the DBGrid is updated.
end;
end;
I don't know why this is. Is this mean I can't switch database from another using Zeoslib component?

The problem is in the TZConnection.Protocol value capitalization. Change the Protocol value from SQLite-3 to sqlite-3.

Related

NO_SQL_DATA error when deleting a record, firedac, delphi 10.3.1

using sql server and delphi 10.3.1, and firedac.
I am using cached updates, with autocommit on.
I keep managing to get my data into a state where the record has been deleted from the database, and I have also deleted that record in the dataset.
then, when it attempts to commit the change to the database(where the data no longer exists), I get an error:
[my application] raised exception class emssqlNativeException with message [firedac][Phys][odbc][sqlncli11.dll] SQL_NO_DATA
and then I can't clear the cached updates flag on the dataset, because there is stuff 'sitting' there.
my question - how can I get it to NOT return that error? because it's really not an error, it's trying to delete a record that no longer exists. I am not finding ANY documentation on the update options on a query, so is there a flag there I need to set?
You can handle update errors in OnUpdateError and perform any additional checks before deciding how to proceed. Blindly pretending all deletes worked would be something like:
procedure TForm1.FDQuery1UpdateError(ASender: TDataSet; AException:
EFDException; ARow: TFDDatSRow; ARequest: TFDUpdateRequest; var AAction:
TFDErrorAction);
begin
if ARequest = ARDelete then AAction := eaApplied;
end;
Read the online help for OnUpdateError for more information.

How to compare the same db at new moments in time

By developing client server applications in Delphi + SQL Server I continuously face the problem to have an exact report of what an action caused on db.
A simple example is:
BEFORE: start "capturing" the DB
user changes a value in an editbox
the user presses a "save" button
AFTER: stop "capturing" the DB
I would like to have a tool that compares the before and after status (I manually capture the BEFORE and AFTER status).
I googled for this kind of tools but all I found are tools for doing data or schema comparison between more datasources.
Thanks.
The following is an extract for an application we have. This code is in a BeforePost event handler that is linked to all of the Dataset components in the application. This linking is done using code as there are a lot of datasets. This doesn't actually log the changes (just lists the fields) but it should be simple enough to change to meet your objective. I don't know if this is exactly right for what you are trying to achieve since you ask for a tool but it would be an effective way of creating a report of all changes
CurrentReport := Format('Table %s modified', [DataSet.Name]);
for i := 0 to DataSet.FieldCount - 1 do
begin
XField := DataSet.Fields[i];
if (XField.FieldKind = fkData) and (XField.Value <> XField.OldValue) then
begin
CurrentReport := CurrentReport + Format(', %s changed', [XField.FieldName])
end;
end;
Note that our code collects a report but only logs it after the post has been successfully completed

How to determine IN APP if a .mdb(access database) created from a delphi app already exist or not?

I am writing a delphi project where I am having to create an access database.
I am using ADOX for the purpose.
Let me admit, I am a novice when it comes to db handling, and I followed the tutorial on net and successfully created by CreateDatabase Procedure. What I want to do is ensure that a database with the given name doesn't exist and ONLY then create the db.
Procedure CreateDatabase(DB_Name:String);
var
path:String;
dataSource : String;
DB : String;
Begin
Path := WindowsDirectory;{Its another function}
delete(Path, 2, length(path));
DB := Path+':\'+DB_Name+'.mdb';
DataSource :=
'Provider=Microsoft.Jet.OLEDB.4.0' +
';Data Source=' + DB +
';Jet OLEDB:Engine Type=4';
Form1.ADOXCatalog1.Create1(DataSource);
End;
I've seen this sort of questions on mySql dbs, but none on access dbs nor have I been able to find any solution to the problem.
Pseudo-Code form of what I want :
if (DatabaseExists(DB_Name)) then
do_something
else
create_db
Some help on this issue will be helpful.
Thank You :)
Regards
Priyabrata Chakraverti
Checking to see if the database exists is simply a matter of checking to see if the database file exists. As Marcus Adams suggested in the comment above, the Delphi function FileExists should do the trick.

TClientDataset ApplyUpdates error because of database table constraint

I have an old Delphi 7 application that loads data from one database table, make many operations and calculation and finally writes records to a destination table.
This old application calls ApplyUpdates every 500 records, for performances reasons.
The problem is that, sometimes, in this bunch of records lies one that will trigger database constraint; Delphi fires an exception on ApplyUpdates.
My problem is I don't know which record is responsible for this exception. There are 500 candidates!
Is it possible to ask TClientDataset which is the offending record?
I do not want to ApplyUpdates foreach appended record for speed issues.
I think you may try to implement the OnReconcileError event which is being fired once for each record that could not be applied to the dataset. So I would try the following code, raSkip means here to skip the current record:
procedure TForm1.ClientDataSet1ReconcileError(DataSet: TCustomClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind; var Action: TReconcileAction);
begin
Action := raSkip;
ShowMessage('The record with ID = ' + DataSet.FieldByName('ID').AsString +
' couldn''t be updated!' + sLineBreak + E.Context);
end;
But please note, I've never tried this before and I'm not sure if it's not too late to ignore the errors raised by the ApplyUpdates function. Forgot to mention, try to use the passed parameter DataSet which should contain the record that couldn't be updated; it might be the way to determine what record caused the problem.
And here is described the updates applying workflow.
Implementing OnReconcileError will give you access to the record and data that is responsible for the exception. An easy to accomplish this is to add a “Reconcile Error Dialog”. It is located on the “New Items” dialog which is displayed by File | New | Other. Once you have added it to your project and used it in the form with the clientdataset. The following code shows how it is invoked.
procedure TForm1.ClientDataSetReconcileError(DataSet: TCustomClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind;
var Action: TReconcileAction);
begin
Action := HandleReconcileError(DataSet, UpdateKind, E);
end;
It will display instead of the exception dialog. It will allow you to view the offending data and select how you want to proceed. It has been over 5 years since I last used it, hopefully I have not forgotten some details.

EDBEngineError 'table is readonly'

I have 3 TQueries: qy_master, qy_detail, qy_detail2, master of qy_detail2 is qy_detail, master of qy_detail is qy_Master, all queries have corresponding data-sources, I placed queries in datamodule, when datamodule create I activate those queries.
In another form I used those queries, when trying 'qy_detail.open' it says 'EDbengine error : Tables is read-only' but no problem when opening qy_detail, I don't modify SQL statements, but I don't know why this error happens.
I also tried with qy_detail.Active := True; this statement also raise error,
I used SQL Server 2005 connected via BDE and ODBC datasources.
Please anyone help me to fix this.
Have you set TQuery.RequestLive = true? RequestLive is False by default forcing query to always return as read-only result set.
From documentation:
A TQuery can return two kinds of result sets: "live" as with TTable
component (users can edit data with data controls, and when a call to
Post occurs changes are sent to database), "read only" for display
purposes only. To request a live result set, set a query component's
RequestLive property to True...

Resources