Subject | Re: How to use DB_KEY from Delphi? |
---|---|
Author | tibotaka |
Post date | 2002-02-25T11:18:48Z |
In my opinion RDB$DB_KEY works pretty well with IBObjects...
IBObjects implements the RDB$DB_KEY as "HEX representation" of it's
binary value (see functions HexTextToBinary() and BinaryToHexText()
in IB_Utils.pas...), so You have to use
instead of
update table set field_x=999
where rdb$db_key='890000000D000000'
something like this code
update table set field_x=999
where rdb$db_key=Chr($89) + Chr($00) + ... + Chr($00)
I known - this is only "Delphi pseudo code", but I think, the idea is
understandable...
E.g. in my Delphi/Firebird application I use on database back-end
stored procedures like this one:
...
CREATE PROCEDURE SPS_CUSTOMER$ID_EXISTS
(AID INTEGER, ARDB$DB_KEY CHAR(8))
RETURNS
(ARESULT SMALLINT)
AS
BEGIN
IF (EXISTS(SELECT * FROM CUSTOMER WHERE (CUSTOMER.ID = :AID)
AND ((:ARDB$DB_KEY IS NULL) OR (CUSTOMER.RDB$DB_KEY
<> :ARDB$DB_KEY)))) THEN
ARESULT = 1;
ELSE
ARESULT = 0;
SUSPEND;
END
...
and in Delphi client application I call this sp with this code:
...
with spCustomerIdExists do
begin
ParamByName('AID').AsString := AString;
ParamByName('ARDB$DB_KEY').AsString :=
HexTextToString(IB_Dataset.FieldByName('RDB$DB_KEY').AsString, 8);
ExecProc;
AResult := FieldByName('AResult').AsInteger;
end;
...
where function HexTextToString() is slightly modificated version of
Jason Wharton's HexTextToBinary() function:
...
function HexTextToString(AHexText: string; ALength: Integer): string;
var
ii: Integer;
tmpBuf: ^Byte;
Bits: Char;
begin
Result := '';
if (Length(AHexText) < ALength * 2) then
begin
Exit;
//raise Exception.Create('Invalid text in HexTextToText');
end;
SetLength(Result, ALength);
tmpBuf := @Result[1];
for ii := 0 to (ALength - 1) do
begin
Bits := AHexText[ ii * 2 + 1 ];
case Bits of
'0'..'9': tmpBuf^ := 16 * ( Ord( Bits ) - Ord( '0' ));
'A'..'F': tmpBuf^ := 16 * ( Ord( Bits ) - Ord( 'A' ) + 10 );
end;
Bits := AHexText[ ii * 2 + 2 ];
case Bits of
'0'..'9': tmpBuf^ := tmpBuf^ + Ord( Bits ) - Ord( '0' );
'A'..'F': tmpBuf^ := tmpBuf^ + Ord( Bits ) - Ord( 'A' ) + 10;
end;
Inc(tmpBuf);
end;
end;
...
(I think this kind of function is missing from IB_Utils.pas if you
want to implement the RDB$DB_KEY as CHAR(8) on Firebird/Interbase
back-end and simultaneously use it in Delphi client application built
with IBObjects - idea for improvement? ;-) )
Sorry for a bit long post, sorry for my english, but I hope it
helps...
Tibor
P.S. I agree on http://www.cvalde.com/ exists an excellent
explaination of RDB$DB_KEY theme and any FB/IB user should read
these...
IBObjects implements the RDB$DB_KEY as "HEX representation" of it's
binary value (see functions HexTextToBinary() and BinaryToHexText()
in IB_Utils.pas...), so You have to use
instead of
update table set field_x=999
where rdb$db_key='890000000D000000'
something like this code
update table set field_x=999
where rdb$db_key=Chr($89) + Chr($00) + ... + Chr($00)
I known - this is only "Delphi pseudo code", but I think, the idea is
understandable...
E.g. in my Delphi/Firebird application I use on database back-end
stored procedures like this one:
...
CREATE PROCEDURE SPS_CUSTOMER$ID_EXISTS
(AID INTEGER, ARDB$DB_KEY CHAR(8))
RETURNS
(ARESULT SMALLINT)
AS
BEGIN
IF (EXISTS(SELECT * FROM CUSTOMER WHERE (CUSTOMER.ID = :AID)
AND ((:ARDB$DB_KEY IS NULL) OR (CUSTOMER.RDB$DB_KEY
<> :ARDB$DB_KEY)))) THEN
ARESULT = 1;
ELSE
ARESULT = 0;
SUSPEND;
END
...
and in Delphi client application I call this sp with this code:
...
with spCustomerIdExists do
begin
ParamByName('AID').AsString := AString;
ParamByName('ARDB$DB_KEY').AsString :=
HexTextToString(IB_Dataset.FieldByName('RDB$DB_KEY').AsString, 8);
ExecProc;
AResult := FieldByName('AResult').AsInteger;
end;
...
where function HexTextToString() is slightly modificated version of
Jason Wharton's HexTextToBinary() function:
...
function HexTextToString(AHexText: string; ALength: Integer): string;
var
ii: Integer;
tmpBuf: ^Byte;
Bits: Char;
begin
Result := '';
if (Length(AHexText) < ALength * 2) then
begin
Exit;
//raise Exception.Create('Invalid text in HexTextToText');
end;
SetLength(Result, ALength);
tmpBuf := @Result[1];
for ii := 0 to (ALength - 1) do
begin
Bits := AHexText[ ii * 2 + 1 ];
case Bits of
'0'..'9': tmpBuf^ := 16 * ( Ord( Bits ) - Ord( '0' ));
'A'..'F': tmpBuf^ := 16 * ( Ord( Bits ) - Ord( 'A' ) + 10 );
end;
Bits := AHexText[ ii * 2 + 2 ];
case Bits of
'0'..'9': tmpBuf^ := tmpBuf^ + Ord( Bits ) - Ord( '0' );
'A'..'F': tmpBuf^ := tmpBuf^ + Ord( Bits ) - Ord( 'A' ) + 10;
end;
Inc(tmpBuf);
end;
end;
...
(I think this kind of function is missing from IB_Utils.pas if you
want to implement the RDB$DB_KEY as CHAR(8) on Firebird/Interbase
back-end and simultaneously use it in Delphi client application built
with IBObjects - idea for improvement? ;-) )
Sorry for a bit long post, sorry for my english, but I hope it
helps...
Tibor
P.S. I agree on http://www.cvalde.com/ exists an excellent
explaination of RDB$DB_KEY theme and any FB/IB user should read
these...
--- In IBObjects@y..., "pepmallorca" <pepmallorca@y...> wrote:
> I can use the DB_KEY in stored procedures defining the variable of
> the type CHAR(8), but if I don't want to use it in a stored
> procedure, and select it with a cursor from Delphi, and then use
it
> for do an UPDATE, for example with IBDSQL, what kind of datatype I
> have to use?
>
> types: String doesn't works, varchar(8) doesn't works
>
> If I use from the program IBSQL, for example, with:
>
> select rdb$db_key from table:
>
> I see a number like:
>
> 890000000D000000
>
> but If I write the next code:
>
> update table set field_x=999 where rdb$db_key='890000000D000000'
>
> it doesn't works, I suppose because the DB_KEY(8) type is not
> compatible with string.
>
> I get DB_KEY works only with stored procedures.
>
>
>
> A lot of problems with DB_KEY, but I think it's a good thing to
solve
> it, isn't it?
>
>
> Thanks,
>
>
> " I have seen some very interesting articles like: 'The mystery of
> rdb$db_key' but I don't find solution for the problems posted here "