Subject Re: [IBO] Multiple dbs and system wide unique keys
Author Marco Menardi <mmenaz@lycosmail.com>
--- In IBObjects@yahoogroups.com, "Brian K. Woods" <brian@e...> wrote:

> Anyone else's two-cents worth is still welcome!
> Brian

Well, the idea could be to build the "very uniwue" key in a stored
procedure (that is also called by the BeforeInsert trigger of the
table, if the provided key is null, just in the case you have to make
manual insertions).
Then, instead of using the "GeneratorLinks" of IBO, simply get the SP
value in the "Before/AfterInsert" event of the query if you have a
query, or just in the Before post if not (so you save keys if the user
press Insert then Cancel...).
I've an algorithm that translates a numerical value to a string, so in
a small space you have plenty of unique values. This is not fine
tuned, and maybe some value is "lost" (it's basicalli a base 10 to
base 36 translation, but I'm not so good in mathematics).
Consider that the number 60.466.175 becomes ZZZZZ if base 36 is used!
here the code, free for use and open to improvements (that, please, I
would like to have back :)

The variables are in italian, and the meaning is about this:

w_numero = number
w_resto = remainder
w_s = (work string)
w_itera = a boolean variable for loops = like "loop_again"

Input:
IN_INTERO = the number taken from the generator (INT64)
IN_BASE= the base of the numeric conversion (i.e. 16=hexadecimal, 36
is the max "compression", uses 0-9 and A-Z from 0 to Z). Max 36


CREATE PROCEDURE INT64_TO_COMPACT_CODE (
IN_INTERO NUMERIC (18, 0),
IN_BASE INTEGER)
RETURNS (
OUT_0Z VARCHAR (30))
AS
DECLARE VARIABLE w_numero NUMERIC(18,0);
DECLARE VARIABLE w_resto NUMERIC(18,0);
DECLARE VARIABLE w_s VARCHAR(30);
DECLARE VARIABLE w_itera INTEGER;
BEGIN
/* trasforma un intero 64bit (es quelli restituiti dai generatori)
in una
stringa equivalente al numero in base 'base'.
Es. se base=16, restituisce una stringa esadecimale,
se base=36, la forma con 0-9 e A-Z, utilizzando al max la
capacita' della stringa
ovvero es. 60.466.175 diventa ZZZZZ */
OUT_0Z = '';
w_numero = IN_INTERO;
w_s = '';
w_itera = 1;
WHILE (w_itera = 1) DO
BEGIN
w_resto = mod(w_numero, IN_BASE);
IF (w_resto <= IN_BASE) THEN
BEGIN
IF (w_resto <= 9) THEN
w_s = ascii_char(ascii_val('0') + w_resto) || w_s;
ELSE
w_s = ascii_char(ascii_val('A') + (w_resto - 10)) || w_s;
END
w_numero = div((w_numero - w_resto), IN_BASE);
IF (w_numero = 0) THEN w_itera = 0;
END
OUT_0Z = w_s;
SUSPEND;
END

regards
Marco Menardi