Remy's answer may be re-formulated as single query.
It may be better, if you gonna prepare it once and then re-open multiple times.
select * from clients where (clientid = :clientid)
and (:clientid is not null)
UNION ALL
select * from clients where (:clientid is null)
This just aggregates two distinct queries (with same results vector) together. And condition just turns one of those off.
Using would be like that:
DBComp.Prepare.
...
DBComp.Close;
DBComp.ParamByName('clientid').Value := clientid;
DBComp.Open;
...
DBComp.Close;
DBComp.ParamByName('clientid').Clear;
DBComp.Open;
However this query would rely on SQL Server optimizer capability to extract query invariant (:clientid is [not] null) and enable/disable query completely. But well, your original query depends upon that too.
Why still use obsolete FB 1.5 ? Won't FB 2.5.2 work better there ?
I think your original query is formulated poorly.
select * from clients where (:clientid = -1) or ((clientid = :clientid) and (:clientid <> -1))
would probably be easier on SQL Server optimizer. Yet i think FB could do better job there. Try to download later FB, and run your query in it, using IDEs like IBExpert or FlameRobin. Re-arranging parenthesis and changing -1 to NULL are obvious ideas to try.
Using BDE is fragile now. It is not very fast, limiting in datatypes and connectivity (no FB/IB Events for example). And would have all sorts of compatibility problems with Vista/Win7 and Win64. If FB/IB is your server of choice, consider switching to some modern component set:
Also it would be good thing to show the table and indices definition and selectivity of those indices.
select * from clients with (index(idx_name)) where (clientid = :clientid or :clientid = -1).