As BigChimp will attest to, I didn't follow the tutorials step by step when I first started them. And that gave me a lot trouble, mostly a complete lack of understanding. So I went back and did them the right way, and things were looking good as they were explained very well. I did the tutorials using a db I created, one that I have interest in (it has two fields in it: a DB_KEY generated by Flamerobin, and NAME (it has seven entries)), and ultimately had issues with the db updating. The DBNavigator seems useless to edit, delete, or post records. The refresh works fine though.
If i click into a cell to change the spelling of a name, let's say, then click edit on the navigator bar, do my edit and click post, then refresh, the editing is gone and field is back to the way it was when before I edited it. Crazy, that.
And if I do the same thing again except not refresh the DBGrid and instead click the "Show Data" button, I get an error:
An error occured while applying the updates in a record: SQLQuery1 : No update query specified and failed to generate one. (No fields for inclusion in where statement found).
Here's the code.
<code>
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.SaveChanges;
// Save edits done by the user, if any.
begin
try
if SQLTransaction1.Active then
// Only if we are within a started transaction...
// otherwise you get "Operation cannot be performed
// on an inactive dataset.
begin
SQLQuery1.ApplyUpdates; // Pass user-generated changes back to database
SQLTransaction1.Commit; // ...and commit them using the transaction.
// SQLTransaction1.Active now is False.
end;
except
on E: EIBDatabaseError do
begin
MessageDlg('Error', 'A database error has occured (SaveChanges Procedure). Technical error message: ' +
E.Message, mterror, [mbOK], 0);
editSQLParam.Text:= '';
end;
end;
end;
procedure TForm1.DBGrid1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState
);
begin
// Check for Delete key being hit and delete the current response
// as long as we're not editing data (in Editor Mode).
if (key=VK_DELETE) and (not(DBGrid1.EditorMode)) then
begin
// delete current record and apply updates to db
SQLQuery1.Delete;
SQLQuery1.ApplyUpdates;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SaveChanges; // Saves changes and commits transaction
try
SQLQuery1.Close;
if not IBConnection1.Connected then
begin
IBConnection1.UserName:= editUsername.Text;
IBConnection1.Password:= editPassword.Text;
IBConnection1.HostName:= editHost.Text;
IBConnection1.DatabaseName:= editDatabaseName.Text;
// Now that we've connected, we set the Edit Boxes
// to ReadOnly so no further changes can be made.
editHost.ReadOnly:= True;
editDatabaseName.ReadOnly:= True;
editUsername.ReadOnly:= True;
editPassword.ReadOnly:= True;
end;
// Show all customer names, or filter for one
if editSQLparam.Text = '' then
SQLQuery1.SQL.Text:= 'select * from customer order by name'
else
begin
SQLQuery1.SQL.Text:= 'select * from customer where name = :name';
SQLQuery1.Params.ParamByName('name').AsString:= editSQLparam.Text;
end;
IBConnection1.Connected:= True; //By default, SQLQuery1.Close sets this to True
SQLTransaction1.Active:= True; //By default, SQLQuery1.Close sets this to True
SQLQuery1.Open;
{
Make sure we don't get problems with inserting blank (=NULL) CUST_NO values, e.g.:
Field CUST_NO is required, but not supplied
We need to tell Lazarus that, while CUST_ID is a primary key, it is not required
when inserting new records.
}
// SQLQuery1.FieldByName('cust_id').Required:= False;
// DBGrid1.Columns[0].Visible:= False; // Hide the cust_id from the user as it is
// the Primary Key
except
on E: EIBDatabaseError do
begin
MessageDlg('Error', 'A database error has occure. Technical error message: ' +
E.Message,mtError,[mbOK],0);
editSQLParam.Text:= '';
end;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
SaveChanges; // Save changes and commits transaction
SQLQuery1.Close;
{ *************************************************
I have omitted the next two lines of code because
SQLQuery1.Close sets them to False anyway...
SQLTransaction1.Active:= False;
IBConnection1.Connected:= False;
*************************************************** }
end;
end.
</code>
If anyone sees an error, please advise. This doesn't seem to be difficult at all, but I can't make it work...even after moving step-by-step through the tutorials. And I've been chopping at this tree all morning and ain't put a dent in it yet. It has me so frustrated that I downloaded QT earlier just to see if if using databases on it was easier. Thing is, I like using Pascal...and I really like Lazarus. I sure hope someone can help me with this.
Landslyde