Muy buena la página relacionada.
Prueba esto que por cortesía de Al González pude conocer. Luego le añadí alguna cosilla.
Necesitas crear esta tabla para que te rule el procedimiento almacenado.
Código SQL
[-]
CREATE GENERATOR GEN_Z_DEFINICION_CAMPO;
CREATE TABLE Z_DEFINICION_CAMPO (
IDCAMPO INTEGER NOT NULL,
TABLA VARCHAR(20) NOT NULL,
CAMPO VARCHAR(20) NOT NULL,
LABEL VARCHAR(20),
MASCARA VARCHAR(20),
TAMANIO INTEGER,
NOMBRE_SI_FK VARCHAR(20),
LABEL_SI_FK VARCHAR(20),
QUERY_SI_FK VARCHAR(200)
);
ALTER TABLE Z_DEFINICION_CAMPO ADD CONSTRAINT FK_Z_DEFINICION_CAMPO PRIMARY KEY (IDCAMPO);
CREATE UNIQUE INDEX Z_DEFINICION_CAMPO_IDX1 ON Z_DEFINICION_CAMPO (TABLA, CAMPO);
SET TERM ^ ;
CREATE OR ALTER TRIGGER Z_DEFINICION_CAMPO_BI0 FOR Z_DEFINICION_CAMPO
ACTIVE BEFORE INSERT POSITION 0
AS
begin
IF (NEW.IDCAMPO IS NULL) THEN
NEW.IDCAMPO = GEN_ID(gen_z_definicion_campo,1);
end
^
SET TERM ; ^
Ahora el procedimiento almacenado
Código SQL
[-]SET TERM ^ ;
CREATE OR ALTER PROCEDURE Z_TABLAS
returns (
tabla varchar(20),
posicion integer,
campo varchar(20),
tipo varchar(25),
longitud integer,
decimales integer,
permite_nulos char(2),
pk integer,
fk_campo varchar(50),
fk_tabla varchar(50),
descripcion varchar(500),
label varchar(20),
mascara varchar(20),
tamanio varchar(20),
nombre_si_fk varchar(20),
label_si_fk varchar(20),
query_si_fk varchar(200))
as
declare variable wtipo integer;
declare variable subtipo integer;
declare variable wprecision integer;
declare variable escala integer;
declare variable nulo integer;
begin
for
Select
RF.RDB$Relation_Name TABLA,
RF.RDB$Field_Name CAMPO,
RF.RDB$Field_Position POSICION,
RF.RDB$Description DESCRIPCION,
F.RDB$Field_Type,
F.RDB$Field_Sub_Type,
F.RDB$Field_Length,
F.RDB$Field_Precision,
F.RDB$Field_Scale,
RF.RDB$Null_Flag
From RDB$Relation_Fields RF
Left Join RDB$Fields F On RF.RDB$Field_Source = F.RDB$Field_Name
Where RF.RDB$System_Flag = 0
order by
RF.RDB$Relation_Name,RF.RDB$Field_Position
INTO :tabla, :campo, posicion, :descripcion, :wtipo, :subtipo, :longitud,
:wprecision, :escala, :nulo
do begin
tipo= 'Desconocido';
if (wtipo = 261) Then
begin
if (subtipo = 1) Then
tipo='Texto BLOb';
else
tipo='BLOb';
end
if (wtipo = 14) Then tipo='Texto Char';
if (wtipo = 40) Then tipo='Texto CString';
if (wtipo = 11) Then tipo='Numérico D_Float';
if (wtipo = 27) Then tipo='Numérico Double' ;
if (wtipo = 10) Then tipo='Numérico Float' ;
if (wtipo = 16) Then
begin
if (subtipo = 1) Then tipo='Numérico';
if (subtipo = 2) Then
tipo='Decimal';
Else
tipo='Entero Int64';
End
if (wtipo = 8) Then
begin
if (subtipo = 1) Then tipo='Numérico';
if (subtipo = 2) Then tipo='Decimal'; Else tipo='Entero Integer';
End
if (wtipo = 9) Then tipo='Quad';
if (wtipo = 7 ) Then
begin
if (subtipo = 1) Then tipo='Numérico';
if (subtipo = 2) Then tipo='Decimal' ;Else tipo='Entero SmallInt';
End
if (wtipo = 12) Then tipo='Fecha Date';
if (wtipo = 13) Then tipo='Hora Time';
if (wtipo = 35) Then tipo='Fecha y hora TimeStamp';
if (wtipo= 37) Then tipo='Texto Varchar';
if (wtipo= 11) Then longitud= wPrecision;
if (wtipo= 27) Then longitud= wPrecision;
if (wtipo= 10) Then longitud= wPrecision;
if (wtipo= 16) Then
if (subtipo = 1 or subtipo =2) Then longitud= wPrecision;
if (wtipo= 8) Then
if (subtipo= 1 or subtipo=2) Then longitud= wPrecision;
if (wtipo= 7 ) Then
if (subtipo=1 or subtipo= 2) Then longitud= wPrecision;
if (escala = 0) Then DECIMALES= Null;
if (escala <> 0 and escala is not null) then DECIMALES= Cast (ESCALA * -1 As integer);
if (NULO = 1) Then PERMITE_NULOS= 'No'; Else PERMITE_NULOS= 'Si';
PK = null;
select i.rdb$field_position
from rdb$relation_constraints rc, rdb$index_segments i, rdb$indices idx
where (i.rdb$index_name = rc.rdb$index_name) and
(idx.rdb$index_name = rc.rdb$index_name) and
(rc.rdb$constraint_type = 'PRIMARY KEY') and
(rc.rdb$relation_name = :TABLA) and
(i.rdb$field_name = :CAMPO)
into :PK ;
if (pk is not null ) then pk = pk+1;
FK_CAMPO = null;
FK_TABLA = Null;
select trim(D.RDB$FIELD_NAME), trim(C.RDB$RELATION_NAME)
from RDB$REF_CONSTRAINTS B, RDB$RELATION_CONSTRAINTS A, RDB$RELATION_CONSTRAINTS C,
RDB$INDEX_SEGMENTS D, RDB$INDEX_SEGMENTS E, RDB$INDICES I
where (A.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY') and
(A.RDB$CONSTRAINT_NAME = B.RDB$CONSTRAINT_NAME) and
(B.RDB$CONST_NAME_UQ=C.RDB$CONSTRAINT_NAME) and (C.RDB$INDEX_NAME=D.RDB$INDEX_NAME) and
(A.RDB$INDEX_NAME=E.RDB$INDEX_NAME) and
(A.RDB$INDEX_NAME=I.RDB$INDEX_NAME) and
(A.RDB$RELATION_NAME = :TABLA) and
(D.RDB$FIELD_NAME = :CAMPO)
into :FK_CAMPO, :FK_TABLA;
LABEL= Null;
MASCARA= null;
TAMANIO=Null;
NOMBRE_SI_FK = Null;
LABEL_SI_FK = Null;
QUERY_SI_FK = Null;
select LABEL,MASCARA, TAMANIO, NOMBRE_SI_FK, LABEL_SI_FK,QUERY_SI_FK
FROM z_definicion_campo
WHERE TABLA=:TABLA AND CAMPO = :CAMPO
INTO :LABEL, :MASCARA, :TAMANIO, :NOMBRE_SI_FK, :LABEL_SI_FK,:QUERY_SI_FK;
suspend;
end
end^
SET TERM ; ^
GRANT SELECT ON Z_DEFINICION_CAMPO TO PROCEDURE Z_TABLAS;
Espero qiue te mole. Si quieres condensar, quita todo lo que dependa de la tabla que te he comentado para crear.
Para usarlo, utiliza "select * from z_tablas". Puedes filtrar por la tabla que quieras.
Saludos