Subject Re: [IBO] Cannot insert more than 1 record using TIBGrid
Author Helen Borrie
At 03:16 PM 3/10/2005 +0000, you wrote:
>I have a TIB_Grid linked to a TIB_DataSource (DataSet is a TIB_Query).
>I can append a record through the grid, but if I try to append a second
>one it's not possible because aparently grid's cells changes to
>ReadOnly ant it's not possible to enter anything.
>TIB_Query has 2 fields, only one is assigned by the user on the Grid,
>value of the other one is assigned internally by code.

When you move off the first inserted record, Post is called. This is the
first moment that anything is submitted to the database. If the Post
fails, you will get an exception from the database and the dataset will
remain in the dssInsert state. You will have to repair or cancel the
insert in order to proceed. In this state, the fields of the problem
record will be writable and you will not be able to move to any other record.

>InsertSQL clause is assigned in TIB_Query's event BeforePost.
>What's wrong?

That is wrong. Set the InsertSQL before the dataset is prepared. The
InsertSQL should be parameterised, to link the KeyFields objects to the
parameters. IBO takes care of matching up the other fields, unless you are
using parameters for the DML that have names different to those of the
linked fields. (In that case, you must assign the values to the parameters
yourself, in the BeforePost event).

Suppose your main statement is

select column1, column2 from mytable

Provided you have the keylinks there and IBO knows them, IBO will
automatically create the InsertSQL as

insert into mytable (column1, column2)
values (:column1, :column2)

At BeforePost, IBO automatically picks up the values from the row buffer
where the insert is being done. By this point, you should have assigned
your internal value and IBO will assign the one that the user entered.

For example, the user entered a value for column2. IBO will do the
equivalent of

mytable.ParamByName('column2').AsWhatever :=
FieldByName('column2').AsWhatever;

Then, for your internally assigned value, you must do

mytable.ParamByName('column1').AsWhatever := AValue;

Of course, if your InsertSQL is custom, e.g. it is a call to a stored
procedure, then you will have to take care of the InsertSQL property
yourself (before the dataset is prepared) and provide any parameters that
are needed. Any matching fieldname/parameter name pairs will be handled
automatically by IBO; and you will have to take care of the rest.

So, for example, your custom InsertSQL might be:

execute procedure New_Recipe (:column1, :userdata)

Here, using your workflow example, you would assign AValue to the parameter
'Column1', as before. But, because you have given a different name to the
second parameter - perhaps because you want to change the user-entered data
for some reason - you must assign this one also.

Helen