Subject Re: [IBO] Using TIB_QUERY
Author Dave Bullar
Thanks Geoff and Tobias for such a full and prompt reply.
You both put the input data into 'Fields' where I tried to use 'Params'.
I did this because I am anxious to avoid stuff I dont need being sent down
the network, and I thought it would be better to 'tell the qry' by setting
it up as an 'Insert' at the beginning that I wasn't interested in getting
stuff sent down.
The Tib_query has a built-in Insert query so why not just transfer that as
the main one.
Was I right up a gum-tree here?

""Geoff Worboys"" <geoff@...> wrote in message
news:008101c13e43$ac000d20$0201950a@hex...
> > Help. Put it how it should be Please !!
> > Does the 'open' method do any 'fetching' ??
>
> Depends on the properties like AutoFetchFirst and AutoFetchAll, and
> also whether you have any data-aware components attempting to read
> from the dataset. IB_Query supports inserting without openning.
>
> You need to realise that TIB_Query is a bufferred dataset. It is
> designed to read multiple records back to the client, and its code is
> setup primarily to interactive with ibo-aware controls. If you are
> not using ibo-data-aware controls then I suggest the use of TIB_Query
> is inappropriate. However, if you wanted to manage the query in code
> you can do something like...
>
> // Set the SQL - IBO will automatically generate
> // the required insert/edit/delete statements for
> // simple SQL selects like this one.
> IB_Query.SQL.Clear;
> IB_Query.SQL.Add('SELECT afield, bfield');
> IB_Query.SQL.Add('FROM atable');
>
> // In most interactive queries you dont add this
> // where clause, but if are wanting to retrieve
> // particular records for edit then this is ONE
> // way of doing it. The alternative is to leave
> // out this line and use the Locate method to
> // find the required record from the buffer or
> // table when the query has been opened.
> IB_Query.SQL.Add('WHERE afield=:MyPKey');
>
> // 'for update' automatically sets RequestLive to true
> // so either add this clause or set RequestLive directly
> // IB_Query.SQL.Add('FOR UPDATE');
> IB_Query.SQL.RequestLive := true;
>
> // This is probably redundant given the where clause
> // above, but here it is anyway. If you got rid of the
> // the parameter and decided to use Locate then this
> // addition is recommended to explicitly tell IBO what
> // the primary key is (instead of making IBO try to
> // determine key itself).
> IB_Query.KeyLinks.Clear;
> IB_Query.KeyLinks.Add('afield');
>
> // Presuming afield is the primary key and is
> // defined using generators you will also want
> IB_Query.GeneratorLinks.Clear;
> IB_Query.GeneratorLinks.Add('afield=mygen');
>
> // Prepare the query - try to setup to do this
> // as rarely as possible as prepare is expensive
> // to performance.
> IB_Query.Prepare;
>
>
> // To insert a new record:
> IB_Query.Insert;
> // with GeneratorLinks attached above we
> // wont need to set afield, IBO will do that
> // automatically.
> IB_Query.FieldByName(...).As... := ...
> <etc>
> IB_Query.Post;
>
> // To edit an existing record:
> // first we need to make sure the required
> // record is the current record.
> IB_Query.ParamByName(...).As... := ...
> IB_Query.First;
> if not IB_Query.Eof then
> begin
> IB_Query.Edit;
> IB_Query.FieldByName(...).As... := ...
> <etc>
> IB_Query.Post;
> end;
> // if we had not defined a where clause with
> // a parameter above, then we could have
> // achieve the same thing by Locate. eg;
> // if Locate( ... ) then
> // begin
> // IB_Query.Edit <etc>
>
>
> // To delete an existing record:
> // first we need to make sure the required
> // record is the current record
> IB_Query.ParamByName(...).As... := ...
> IB_Query.First;
> if not IB_Query.Eof then
> begin
> IB_Query.Delete;
> // if AutoPostDelete is false then which you
> // may decide to do if you want to setup a prompt
> // to confirm delete at this point. If so then
> // you would need to have an explicit call to post.
> // IB_Query.Post;
> end;
>
> The above use of TIB_Query (using the parameter to select only a
> single record) is an example of using TIB_Query as though it were a
> TIB_Cursor. In fact you can same some resources by replacing
> TIB_Query with TIB_Cursor and still do exactly what I showed above.
> (You cant use Locate with TIB_Cursor, you must use the parameter
> situation described above, locate only works with the buffered dataset
> IB_Query.)
>
> IMO there is no advantage in using TIB_Query in the above example.
> However if you were wanting to have the records buffered at the client
> for some other reason, then you could remove the where clause and
> parameter shown above and use Locate instead of ParamByName, First.
>
> So the above example is valid for IB_Query or IB_Cursor. Note that
> you can also use TIB_DSQL something like...
>
> // to Insert
> IB_DSQL.SQL.Clear;
> IB_DSQL.SQL.Add('INSERT INTO atable( afield, bfield )');
> IB_DSQL.SQL.Add('VALUES( :afield, :bfield )');
> IB_DSQL.Prepare;
> IB_DSQL.ParamByName(...).As... := ...
> <etc>
> IB_DSQL.Execute;
>
> // to Edit
> IB_DSQL.SQL.Clear;
> IB_DSQL.SQL.Add('UDPATE atable');
> IB_DSQL.SQL.Add('SET bfield=:bfield');
> IB_DSQL.SQL.Add('WHERE afield=:afield');
> IB_DSQL.Prepare;
> IB_DSQL.ParamByName(...).As... := ...
> <etc>
> IB_DSQL.Execute;
>
> // to Delete
> IB_DSQL.SQL.Clear;
> IB_DSQL.SQL.Add('DELETE FROM atable');
> IB_DSQL.SQL.Add('WHERE afield=:afield');
> IB_DSQL.Prepare;
> IB_DSQL.ParamByName(...).As... := ...
> <etc>
> IB_DSQL.Execute;
>
> This will save you even more resources, since IB_DSQL contains even
> less overhead than IB_Cursor.
>
>
> Note: For simplicity I have shown ParamByName and FieldByName above.
> These are acceptable for simple situations but keep in mind that for
> looping situations (eg importing many records) it is better to keep
> track of the column references and use them directly. eg:
>
> var
> ACol, BCol: TIB_Column;
> begin
> IB_DSQL.SQL.Clear;
> IB_DSQL.SQL.Add('INSERT INTO atable( afield, bfield )');
> IB_DSQL.SQL.Add('VALUES( :afield, :bfield )');
> IB_DSQL.Prepare;
> ACol := IB_DSQL.ParamByName('afield');
> BCol := IB_DSQL.ParamByName('bfield');
> for <<some loop criteria>> do
> begin
> ACol.As... := ...
> BCol.As... := ...
> IB_DSQL.Execute;
> end;
> end;
>
>
> There are more complete examples of managing IB_Cursor and IB_DSQL in
> code in some of the sample applications. The idea of the above was to
> try and demonstrate the main differences between how you use query,
> cursor an dsql. It is really up to you to decide what is going to fit
> best with your application - I will simply reiterate that ib_query
> does not *appear* to fit with what you have explained so far. I
> recommend either ib_cursor or ib_dsql.
>
> HTH
>
> Geoff Worboys
> Telesis Computing
>
>
>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
>