Как получить полный текст процедуры из базы данных FireBird
начало этого разговора было положено в конференциях http://www.sql.ru/forum/actualthread.aspx?tid=901951 отдельное спасибо автору сайта ibase.ru Источник http://www.ibase.ru/devinfo/sysqry.htm
1. Получение списка полей и их
типов по таблицам:
select R.RDB$RELATION_NAME, R.RDB$FIELD_POSITION,
R.RDB$FIELD_NAME,
F.RDB$FIELD_LENGTH, F.RDB$FIELD_TYPE,
F.RDB$FIELD_SCALE, F.RDB$FIELD_SUB_TYPE
from RDB$FIELDS F, RDB$RELATION_FIELDS
R
where F.RDB$FIELD_NAME = R.RDB$FIELD_SOURCE
and R.RDB$SYSTEM_FLAG = 0
order by R.RDB$RELATION_NAME, R.RDB$FIELD_POSITION
Если вам не нравится нумерация полей с 0, то можно вместо R.RDB$FIELD_POSITION
написать R.RDB$FIELD_POSITION+1. Для получения списка полей конкретной таблицы
нужно добавить соответствующее условие к where - and RDB$RELATION_NAME = 'MYTABLE'.
Функция Delphi позволяет получить полный текст процедуры вмести с заголовком входных и выходных параметров.
ParamSm:TIBQuery; // ссылка на объект SQL FunctionName:string // имя процедуры
Function GetAllBodyFromProcedure(ParamSm:TIBQuery;FunctionName:string):string;
Function GetSQLFromMod(Nametext:string):string; begin Result:='select pr.rdb$procedure_name,'+#13+#10+ 'pr.rdb$procedure_source,'+#13+#10+ 'pp.rdb$parameter_name,'+#13+#10+ 'pp.rdb$parameter_type,'+#13+#10+ 'fs.rdb$field_name,'+#13+#10+ 'fs.rdb$field_type,'+#13+#10+ 'fs.rdb$field_length,'+#13+#10+ 'fs.rdb$field_scale,'+#13+#10+ 'fs.rdb$field_sub_type,'+#13+#10+ 'fs.rdb$segment_length,'+#13+#10+ 'fs.rdb$dimensions,'+#13+#10+ 'cr.rdb$character_set_name,'+#13+#10+ 'co.rdb$collation_name,'+#13+#10+ 'pp.rdb$parameter_number,'+#13+#10+ 'fs.rdb$character_length,'+#13+#10+ 'pp.rdb$description,'+#13+#10+ 'pr.rdb$description,'+#13+#10+ 'fs.rdb$default_source,'+#13+#10+ 'fs.rdb$field_precision,'+#13+#10+ 'cast(0 as integer),'+#13+#10+ 'pp.rdb$field_source,'+#13+#10+ 'fs.rdb$default_source,'+#13+#10+ 'cast(0 as integer),'+#13+#10+ 'cast(null as varchar(64)),'+#13+#10+ 'cast(null as varchar(64)),'+#13+#10+ 'cast(null as varchar(64)),'+#13+#10+ 'cr.rdb$default_collate_name'+#13+#10+ ''+#13+#10+ 'from rdb$procedures pr'+#13+#10+ 'left join rdb$procedure_parameters pp on pp.rdb$procedure_name = pr.rdb$procedure_name'+#13+#10+ 'left join rdb$fields fs on fs.rdb$field_name = pp.rdb$field_source'+#13+#10+ 'left join rdb$character_sets cr on fs.rdb$character_set_id = cr.rdb$character_set_id'+#13+#10+ 'left join rdb$collations co on ((fs.rdb$collation_id = co.rdb$collation_id) and'+#13+#10+ '(fs.rdb$character_set_id = co.rdb$character_set_id))'+#13+#10+ 'where pr.rdb$procedure_name = '+#39+Nametext+#39+''+#13+#10+ 'order by pp.rdb$parameter_type, pp.rdb$parameter_number'; end; Function DeeleteProbel(s:string):string; var l,x:integer; s2:string; begin l:=length(s); s2:=''; for X:=1 to l do begin if s[x]=' ' then else s2:=s2+s[x]; end; result:=s2; end; Function GetTypeFromFieBird(fullname:string;DataType,Precision,Scale,Length_m,SubType:integer):string;
var i:integer; s:string; begin s:=' '+DeeleteProbel(fullname)+' '; case DataType of 7 : begin if Precision = 0 then s:=s+'SMALLINT' else s:=s+'NUMERIC('+IntToStr(Precision)+','+IntToStr(-Scale)+')'; end; 8 : begin if Precision = 0 then s:=s+'INTEGER' else s:=s+'NUMERIC('+IntToStr(Precision)+','+IntToStr(-Scale)+')'; end;
9 : s:=s+'TIMESTAMP'; 10 : s:=s+'FLOAT'; 12 : s:=s+'DATE'; 13 : s:=s+'TIME'; 14 : s:=s+'CHAR('+IntToStr(Length_m)+')'; 16 : begin if Precision = 0 then s:=s+'BIGINT' else s:=s+'NUMERIC('+IntToStr(Precision)+','+IntToStr(-Scale)+')'; end; 17 : s:=s+'BOOLEAN'; 27 : begin if Scale = 0 then s:=s+'DOUBLE PRECISION' else s:=s+'NUMERIC(15,'+IntToStr(-Scale)+')'; end; 35 : s:=s+'TIMESTAMP'; 37 : s:=s+'VARCHAR('+IntToStr(Length_m)+')'; 45, 261 : s:=s+'BLOB SUBTYPE '+IntToStr(SubType); end; result:=s; end;
Function GetAllParam(s:string):string; var fullname:string; DataType,Precision,Scale,Length_m,SubType:integer; s2:string; first:boolean; inputParam:boolean; firstInputparam:boolean; begin s2:=''; ParamSm.SQL.Text:=GetSQLFromMod(s); ParamSm.Open; first:=true; inputParam:=false; firstInputparam:=true;
repeat fullname:=' '+ParamSm.Fieldbyname('rdb$parameter_name').AsString; DataType:=ParamSm.Fieldbyname('rdb$field_type').AsInteger;
if ParamSm.Fieldbyname('rdb$parameter_type').AsInteger=0 then begin inputParam:=true; if firstInputparam then s2:=s2+' ('+#13+#10; firstInputparam:=false; end;
if ParamSm.Fieldbyname('rdb$parameter_type').AsInteger=1 then begin if first then begin s2:=copy(s2,1,length(s2)-3); if inputParam then s2:=s2+')'; s2:=s2+' '+#13+#10+'returns ('+#13+#10; end; first:=false; end;
Precision:=ParamSm.Fieldbyname('rdb$field_precision').AsInteger; Scale:=ParamSm.Fieldbyname('rdb$field_scale').AsInteger; Length_m:=ParamSm.Fieldbyname('rdb$field_length').AsInteger; SubType:=ParamSm.Fieldbyname('rdb$field_sub_type').AsInteger; ParamSm.next; s2:=s2+GetTypeFromFieBird(fullname,DataType,Precision,Scale,Length_m,SubType)+','+#13+#10; until ParamSm.eof; if not first then begin s2:=copy(s2,1,length(s2)-3); s2:=s2+')'+#13+#10; end else begin s2:=copy(s2,1,length(s2)-3); s2:=s2+')'+#13+#10; end; s2:=s2+'as'+#13+#10;
result:=s2;
end; Function GetCaption(sname:string;title:string='create procedure'):string; begin result := title+' '+DeeleteProbel(sname); end; Function GetAllProcedure(sname:string):string; var s2:string; Text:string; begin s2:=GetCaption(sname); s2:=s2+GetAllParam(sname); ParamSm.SQL.Text:='SELECT * FROM RDB$PROCEDURES WHERE RDB$PROCEDURE_NAME ="'+sname+'"'; ParamSm.open; Text:=ParamSm.FieldByName('RDB$PROCEDURE_SOURCE').AsString; result:=s2+text; end;
begin result:=GetAllProcedure(Functionname); end;
|