Subject Re: [IBO] tib_cursor error - attempt to fetch past the last record
Author Helen Borrie (TeamIBO)
At 11:48 PM 09-01-02 +0000, you wrote:
>My tib_cursor has the following sql and delphi code. I get the below
>error (on the open statement

TIB_Cursor is a non-buffered dataset, so calls Open and Close with both raise that ISC error. Remove the call to Close and use First.

Also, change the Prepare call to

If not Prepared then Prepare ;
and place it BEFORE any reference to Params[].
(ParamByName actually does this line itself, so omit it. Use it if you call Params[] instead.)

>or on a first statement if I use that
>instead). I have checked all the sample programs and faq and can't
>find what I'm doing wrong.

>Also, does a tib_cursor need keylinks?

If you are going to be performing any operations based on identifying rows in the underlying tables then you must have KeyLinks and they must uniquely identify each row in the output dataset.

>-----------------------------------------------
>sql =
>
>SELECT
> I.ITEMID, I.ORDERID, I.PARTID, I.QUANTITY, I.UM,
> I.ITEMDATE, P.PARTNUMBER, O.PURCHASEORDER
>FROM
> T_ITEM I, T_ORDER O, T_PART P
>WHERE
> I.ITEMID = :P_ITEMID
> AND I.ORDERID = O.ORDERID
> AND I.PARTID = P.PARTID
>
>-----------------------------------------------

This form of inner join statement is not IBO-friendly. You should either replace this statement with an SQL-92 format statement, or use JoinLinks to inform IBO which sub-clauses in your WHERE clause are JOIN criteria (in this case, that means all of them, because you have no bona fide WHERE sub-clauses at all).

This statement will avoid the problem altogether:

SELECT
I.ITEMID, I.ORDERID, I.PARTID, I.QUANTITY, I.UM,
I.ITEMDATE, P.PARTNUMBER, O.PURCHASEORDER
FROM
T_ITEM I
join T_ORDER O on I.ORDERID = O.ORDERID
join T_PART P on I.ITEMID = :P_ITEMID
and I.PARTID = P.PARTID

>delphi code =
>
> with MyCursor do begin
> if Active then Close;
> ParamByName('P_ITEMID').AsInteger := CurrentId;
> Prepare;
> Open;
> end;

replace with

with MyCursor do begin
// if not Prepared then Prepare; NOT NECESSARY WITH ParamByName()
ParamByName('P_ITEMID').AsInteger := CurrentId;
First;
end;


regards,
Helen Borrie (TeamIBO Support)

** Please don't email your support questions privately **
Ask on the list and everyone benefits
Don't forget the IB Objects online FAQ - link from any page at www.ibobjects.com