Subject Re: [IBO] Getting validation source from a domain
Author Helen Borrie
At 12:50 PM 18/10/2006, you wrote:
>I am using the code below to try to get the validation source for a
>domain--but it doesn't return anything. I try the same SQL in IBExpert
>(which last I knew used IBO)

It doesn't. It uses FIBPlus, which doesn't have a component
equivalent to TIB_Cursor.

>and it returns a value... what am Iforgetting?

IBExpert uses an ordinary query component for unidirectional result
sets, so calling Open will show the first output row, if
any. TIB_Cursor doesn't work like that.

> lCursor := CreateCursor('SELECT First 1 RDB$VALIDATION_SOURCE
> FROM RDB$FIELDS WHERE RDB$FIELD_NAME = ''%s''',
> [UpperCase(aName)]);

I'm dubious about the above - it's part of the Metadata
components...however, perhaps that's what you're working with. I
just can't find a public declaration for that function.

But, supposing you are able to return a TIB_Cursor to ICursor, there
are things missing from your ICursor object - ib_connection property,
for example; and I'd also want to set its IB_Transaction property explicitly.

> try
> try
> if not (FTx.TransactionIsActive or FTx.InTransaction) then
> FTx.StartTransaction;
> lCursor.Open;

Let's suppose you get this far. Calling Open on a TIB_Cursor doesn't
place you on a row. Call First instead.

> result := lCursor.RecordCount > 0;

RecordCount is meaningless. An IB_Cursor doesn't know about it. It
has a single-row buffer.

> if result then
> aValidationSource := lCursor.Fields[0].AsString

Not quite this simple. The field you are querying is a blob. It
happens to contain text but it's a subtype 1 blob. You can assign a
blob to a TStrings of some sort (stringlist, memo, etc.) and read and
concatenate its Strings or read its Text.

> else
> aValidationSource := '';
> FTx.Commit;
> except
> FTx.Rollback;
> raise;
> end;
> finally
> lCursor.Free;
> end;

With no guarantees ('cos I have no idea what you're working with
here, v-a-v connection, transaction, etc.) work on replacing this
dataset-oriented code with row-oriented code, such as:

...
var
aStrings: TStringlist;
...
....
.....
with ICursor do
begin
if (
(not (IB_Transaction.TransactionIsActive)) or
(not IB_Transaction.InTransaction)) ) then
IB_Transaction.StartTransaction;
First;
result := not EOF;
if result then
try
aStrings := TStringlist.Create;
TIB_ColumnBlob(Fields[0]).AssignTo(aStrings);
aValidationSource := aStrings.Text;
finally
aStrings.Free;
end
else
aValidationSource := '';
.....

Also, you don't need SELECT FIRST in your SQL. A domain has only one
record in RDB$FIELDS. If you actually want to target the first
validation rule in the blob, you'll need to process the stringlist
string-by-string in some fashion.

Helen