/Gedemin/Common/gdUpdateIndiceStat.pas

http://gedemin.googlecode.com/ · Pascal · 574 lines · 491 code · 73 blank · 10 comment · 31 complexity · a60d1184a530d131cf311b196d4fa10b MD5 · raw file

  1. unit gdUpdateIndiceStat;
  2. interface
  3. uses
  4. IBDatabase;
  5. type
  6. Tcst_def_KeyWords =
  7. (CURRENT_DATE, CURRENT_TIME, CURRENT_USER, CURRENT_ROLE, CURRENT_TIMESTAMP);
  8. const
  9. cst_def_KeyWords: array[Tcst_def_KeyWords] of String =
  10. ('CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_USER', 'CURRENT_ROLE', 'CURRENT_TIMESTAMP');
  11. function GetDefValueInQuotes(const DefaultValue: String): String;
  12. function GetDomainText(ADataBase : TIBDataBase; FieldName : String; const isCharSet: Boolean = True): String;
  13. function GetParamsText(ProcedureName : String; ADataBase : TIBDataBase): String;
  14. procedure UpdateIndicesStat(ADataBase : TIBDataBase);
  15. procedure RecompileTriggers(ADataBase : TIBDataBase);
  16. procedure RecompileProcedures(ADataBase : TIBDataBase);
  17. procedure ReCreateComputedFields(ADataBase : TIBDataBase);
  18. procedure ReCreateView(ADataBase : TIBDataBase);
  19. implementation
  20. uses
  21. IBSQL, IBHeader, IBCustomDataSet, SysUtils, Classes, at_frmSQLProcess;
  22. procedure UpdateIndicesStat(ADataBase : TIBDataBase);
  23. var
  24. q1, q2: TIBSQL;
  25. Tr, ReadTr: TIBTransaction;
  26. begin
  27. q1 := TIBSQL.Create(nil);
  28. q2 := TIBSQL.Create(nil);
  29. Tr := TIBTransaction.Create(nil);
  30. ReadTr := TIBTransaction.Create(nil);
  31. try
  32. Tr.DefaultDatabase := ADataBase;
  33. ReadTr.DefaultDatabase := ADataBase;
  34. ReadTr.StartTransaction;
  35. q1.Transaction := Tr;
  36. q2.Transaction := ReadTr;
  37. q2.SQL.Text := 'SELECT rdb$index_name FROM rdb$indices ';
  38. q2.ExecQuery;
  39. while not q2.EOF do
  40. begin
  41. Tr.StartTransaction;
  42. AddText('?????????? ?????????? ??????? ' + q2.Fields[0].AsTrimString);
  43. q1.SQL.Text := 'SET STATISTICS INDEX "' + q2.Fields[0].AsTrimString + '"';;
  44. q1.ExecQuery;
  45. q1.Close;
  46. Tr.Commit;
  47. q2.Next;
  48. end;
  49. q2.Close;
  50. ReadTr.Commit;
  51. finally
  52. q1.Free;
  53. q2.Free;
  54. Tr.Free;
  55. ReadTr.Free;
  56. end;
  57. end;
  58. procedure RecompileTriggers(ADataBase : TIBDataBase);
  59. var
  60. q1, q2: TIBSQL;
  61. Tr, ReadTr: TIBTransaction;
  62. begin
  63. q1 := TIBSQL.Create(nil);
  64. q2 := TIBSQL.Create(nil);
  65. Tr := TIBTransaction.Create(nil);
  66. ReadTr := TIBTransaction.Create(nil);
  67. try
  68. Tr.DefaultDatabase := ADataBase;
  69. ReadTr.DefaultDatabase := ADataBase;
  70. ReadTr.StartTransaction;
  71. q1.Transaction := Tr;
  72. q2.Transaction := ReadTr;
  73. q2.SQL.Text := 'SELECT tr.RDB$TRIGGER_NAME, tr.RDB$TRIGGER_SOURCE FROM RDB$TRIGGERS tr '#13#10 +
  74. 'WHERE NOT tr.RDB$TRIGGER_SOURCE IS NULL'#13#10 +
  75. 'AND NOT tr.RDB$TRIGGER_NAME LIKE ''CHECK%''';
  76. q2.ExecQuery;
  77. while not q2.EOF do
  78. begin
  79. Tr.StartTransaction;
  80. AddText('?????????????? ???????? ' + q2.Fields[0].AsTrimString);
  81. q1.SQL.Text := 'ALTER TRIGGER "' + q2.Fields[0].AsTrimString + '" ' + q2.Fields[1].AsTrimString;
  82. q1.ParamCheck := False;
  83. q1.ExecQuery;
  84. q1.Close;
  85. Tr.Commit;
  86. q2.Next;
  87. end;
  88. q2.Close;
  89. ReadTr.Commit;
  90. finally
  91. q1.Free;
  92. q2.Free;
  93. Tr.Free;
  94. ReadTr.Free;
  95. end;
  96. end;
  97. procedure RecompileProcedures(ADataBase : TIBDataBase);
  98. var
  99. q1, q2: TIBSQL;
  100. Tr, ReadTr: TIBTransaction;
  101. begin
  102. q1 := TIBSQL.Create(nil);
  103. q2 := TIBSQL.Create(nil);
  104. Tr := TIBTransaction.Create(nil);
  105. ReadTr := TIBTransaction.Create(nil);
  106. try
  107. Tr.DefaultDatabase := ADataBase;
  108. ReadTr.DefaultDatabase := ADataBase;
  109. ReadTr.StartTransaction;
  110. q1.Transaction := Tr;
  111. q2.Transaction := ReadTr;
  112. q2.SQL.Text := 'SELECT pr.RDB$PROCEDURE_NAME, pr.RDB$PROCEDURE_SOURCE FROM RDB$PROCEDURES pr '#13#10 +
  113. 'WHERE NOT pr.RDB$PROCEDURE_SOURCE IS NULL';
  114. q2.ExecQuery;
  115. while not q2.EOF do
  116. begin
  117. Tr.StartTransaction;
  118. AddText('?????????????? ????????? ' + q2.Fields[0].AsTrimString);
  119. q1.SQL.Text := 'ALTER PROCEDURE "' + q2.Fields[0].AsTrimString + '" ' + GetParamsText(q2.FieldByName('RDB$PROCEDURE_NAME').AsString , ADataBase) +
  120. ' AS ' + q2.Fields[1].AsTrimString;
  121. q1.ParamCheck := False;
  122. q1.ExecQuery;
  123. q1.Close;
  124. Tr.Commit;
  125. q2.Next;
  126. end;
  127. q2.Close;
  128. ReadTr.Commit;
  129. finally
  130. q1.Free;
  131. q2.Free;
  132. Tr.Free;
  133. ReadTr.Free;
  134. end;
  135. end;
  136. function GetParamsText(ProcedureName : String; ADataBase : TIBDataBase ): String;
  137. var
  138. ibsql: TIBSQl;
  139. S1, S2: String;
  140. Tr : TIBTransaction;
  141. begin
  142. Result := '';
  143. ibsql := TIBSQL.Create(nil);;
  144. Tr := TIBTransaction.Create(nil);
  145. try
  146. Tr.DefaultDatabase := ADataBase;
  147. Tr.StartTransaction;
  148. ibsql.Transaction := Tr;
  149. ibsql.SQL.Text := 'SELECT * FROM rdb$procedure_parameters pr ' +
  150. 'WHERE pr.rdb$procedure_name = :pn AND pr.rdb$parameter_type = :pt ' +
  151. 'ORDER BY pr.rdb$parameter_number ASC ';
  152. ibsql.ParamByName('pn').AsString := ProcedureName;
  153. ibsql.ParamByName('pt').AsInteger := 0;
  154. ibsql.ExecQuery;
  155. S1 := '';
  156. while not ibsql.EOF do
  157. begin
  158. if S1 = '' then
  159. S1 := '('#13#10;
  160. S1 := S1 + ' ' + Trim(ibsql.FieldByName('rdb$parameter_name').AsString) + ' ' +
  161. GetDomainText(ADataBase ,ibsql.FieldByName('rdb$field_source').AsString, False);
  162. ibsql.Next;
  163. if not ibsql.EOF then
  164. S1 := S1 + ','#13#10
  165. else
  166. S1 := S1 + ')';
  167. end;
  168. S1 := S1 + #13#10;
  169. ibsql.Close;
  170. ibsql.ParamByName('pt').AsInteger := 1;
  171. ibsql.ExecQuery;
  172. S2 := '';
  173. while not ibsql.EOF do
  174. begin
  175. if S2 = '' then
  176. S2 := 'RETURNS ( '#13#10;
  177. S2 := S2 + ' ' + Trim(ibsql.FieldByName('rdb$parameter_name').AsString) + ' ' + GetDomainText(ADataBase, ibsql.FieldByName('rdb$field_source').AsString, False);
  178. ibsql.Next;
  179. if not ibsql.EOF then
  180. S2 := S2 + ','#13#10
  181. else
  182. S2 := S2 + ')'#13#10;
  183. end;
  184. Result := S1 + S2;
  185. Tr.Commit
  186. finally
  187. ibsql.Free;
  188. Tr.Free;
  189. end;
  190. end;
  191. function GetDomainText(ADataBase : TIBDataBase; FieldName :String; const isCharSet: Boolean = True): String;
  192. function FormFloatDomain(dsDomain: TIBSQL): String;
  193. var
  194. fscale: Integer;
  195. begin
  196. if dsDomain.FieldByName('fsubtype').AsInteger = 1 then
  197. Result := 'NUMERIC'
  198. else
  199. Result := 'DECIMAL';
  200. if dsDomain.FieldByName('fscale').AsInteger < 0 then
  201. fscale := -dsDomain.FieldByName('fscale').AsInteger
  202. else
  203. fscale := dsDomain.FieldByName('fscale').AsInteger;
  204. if dsDomain.FieldByName('fprecision').AsInteger = 0 then
  205. Result := Format('%s(9, %s)',
  206. [Result, IntToStr(fscale)])
  207. else
  208. Result := Format('%s(%s, %s)',
  209. [Result, dsDomain.FieldByName('fprecision').AsString, IntToStr(fscale)]);
  210. end;
  211. function GetDomain (dsDomain: TIBSQL): String;
  212. begin
  213. case dsDomain.FieldByName('ffieldtype').AsInteger of
  214. blr_Text, blr_varying:
  215. begin
  216. if dsDomain.FieldByName('ffieldtype').AsInteger = blr_Text then
  217. Result := 'CHAR'
  218. else
  219. Result := 'VARCHAR';
  220. Result := Format('%s(%s)', [Result, dsDomain.FieldByName('fcharlength').AsString]);
  221. if isCharSet and (dsDomain.FieldByName('CHARSET').AsString <> '') then
  222. begin
  223. Result := Format('%s CHARACTER SET %s',
  224. [Result, Trim(dsDomain.FieldByName('CHARSET').AsString)]);
  225. end;
  226. end;
  227. blr_d_float, blr_double, blr_float:
  228. Result := 'DOUBLE PRECISION';
  229. blr_int64:
  230. if (dsDomain.FieldByName('fsubtype').AsInteger > 0) or
  231. (dsDomain.FieldByName('fprecision').AsInteger > 0) or
  232. (dsDomain.FieldByName('fscale').AsInteger < 0) then
  233. begin
  234. Result := FormFloatDomain(dsDomain)
  235. end else
  236. Result := 'BIGINT';
  237. blr_long:
  238. if (dsDomain.FieldByName('fsubtype').AsInteger > 0) or
  239. (dsDomain.FieldByName('fprecision').AsInteger > 0) or
  240. (dsDomain.FieldByName('fscale').AsInteger < 0) then
  241. begin
  242. Result := FormFloatDomain(dsDomain)
  243. end else
  244. Result := 'INTEGER';
  245. blr_short:
  246. if (dsDomain.FieldByName('fsubtype').AsInteger > 0) or
  247. (dsDomain.FieldByName('fprecision').AsInteger > 0) or
  248. (dsDomain.FieldByName('fscale').AsInteger < 0) then
  249. begin
  250. Result := FormFloatDomain(dsDomain)
  251. end else
  252. Result := 'SMALLINT';
  253. blr_sql_time:
  254. Result := 'TIME';
  255. blr_sql_date:
  256. Result := 'DATE';
  257. blr_timestamp:
  258. Result := 'TIMESTAMP';
  259. blr_blob:
  260. begin
  261. Result := 'BLOB';
  262. Result := Format
  263. (
  264. ' %s SUB_TYPE %s SEGMENT SIZE %s',
  265. [
  266. Result,
  267. dsDomain.FieldByName('fsubtype').AsString,
  268. dsDomain.FieldByName('seglength').AsString
  269. ]
  270. );
  271. if isCharSet and (dsDomain.FieldByName('CHARSET').AsString <> '') then
  272. begin
  273. Result := Format('%s CHARACTER SET %s',
  274. [Result, dsDomain.FieldByName('CHARSET').AsString]);
  275. end;
  276. end;
  277. end;
  278. Result := Trim(Result);
  279. end;
  280. var
  281. qry: TIBSQL;
  282. Transaction : TIBTransaction;
  283. begin
  284. qry := TIBSQL.Create(nil);
  285. Transaction := TIBTransaction.Create(nil);
  286. try
  287. Transaction.DefaultDatabase := ADataBase;
  288. Transaction.StartTransaction;
  289. qry.Transaction := Transaction;
  290. try
  291. qry.SQL.Text := 'SELECT ' +
  292. ' /* z.*, refr.lname as reflname, refrf.lname as reflistlname, ' +
  293. ' setr.lname as setlistlname, */ rdb.rdb$null_flag AS flag, ' +
  294. ' rdb.rdb$field_type as ffieldtype, ' +
  295. ' rdb.rdb$field_sub_type as fsubtype, ' +
  296. ' rdb.rdb$field_precision as fprecision, ' +
  297. ' rdb.rdb$field_scale as fscale, ' +
  298. ' rdb.rdb$field_length as flength, ' +
  299. ' rdb.rdb$character_length as fcharlength, ' +
  300. ' rdb.rdb$segment_length as seglength, ' +
  301. ' rdb.rdb$validation_source AS checksource, ' +
  302. ' rdb.rdb$default_source as defsource, ' +
  303. ' rdb.rdb$computed_source as computed_value, ' +
  304. ' cs.rdb$character_set_name AS charset, ' +
  305. ' cl.rdb$collation_name AS collation ' +
  306. ' FROM rdb$fields rdb ' +
  307. ' LEFT JOIN ' +
  308. ' rdb$character_sets cs ' +
  309. ' ON ' +
  310. ' rdb.rdb$character_set_id = cs.rdb$character_set_id ' +
  311. ' LEFT JOIN ' +
  312. ' rdb$collations cl ' +
  313. ' ON ' +
  314. ' rdb.rdb$collation_id = cl.rdb$collation_id ' +
  315. ' AND ' +
  316. ' rdb.rdb$character_set_id = cl.rdb$character_set_id ' +
  317. ' LEFT JOIN at_fields z ON ' +
  318. ' rdb.rdb$field_name = z.fieldname ' +
  319. ' WHERE rdb.rdb$field_name = :fieldname ';
  320. qry.ParamByName('fieldname').AsString := FieldName;
  321. qry.ExecQuery;
  322. if qry.RecordCount > 0 then
  323. Result := GetDomain(qry)
  324. else
  325. raise Exception.Create('??????????? ??? ??????');
  326. if Transaction.InTransaction then
  327. Transaction.Commit;
  328. except
  329. if Transaction.InTransaction then
  330. Transaction.Rollback;
  331. raise;
  332. end;
  333. finally
  334. qry.Free;
  335. Transaction.Free;
  336. end;
  337. end;
  338. //????????? ???????? ?? ????????? ? ???????
  339. //??? ???? ???? ????????: ???? ???????? ??? ? ????????, ?? ??? ??? ? ????????????
  340. //? ???????? ??????, ???? ??????? ??????????? ?????? ??????, ?? ??? ???????????
  341. function GetDefValueInQuotes(const DefaultValue: String): String;
  342. var
  343. I: Integer;
  344. DefSt: String;
  345. L: Tcst_def_KeyWords;
  346. begin
  347. if AnsiPos('DEFAULT', Trim(AnsiUpperCase(DefaultValue))) = 1 then
  348. DefSt := Trim(Copy(Trim(DefaultValue), 8, Length(Trim(DefaultValue)) - 1))
  349. else
  350. DefSt := DefaultValue;
  351. for L := Low(cst_def_KeyWords) to High(cst_def_KeyWords) do
  352. begin
  353. if AnsiCompareText(DefSt, cst_def_KeyWords[L]) = 0 then
  354. begin
  355. Result := DefSt;
  356. Exit;
  357. end;
  358. end;
  359. if (DefSt[1] = '''') and (DefSt[Length(DefSt)] = '''') then
  360. begin
  361. Result := DefSt;
  362. end else
  363. begin
  364. Result := '';
  365. for I := 1 to Length(DefSt) do
  366. begin
  367. if DefSt[I] = '''' then
  368. Result := Result + '''';
  369. Result := Result + DefSt[I];
  370. end;
  371. Result := '''' + Result + '''';
  372. end;
  373. end;
  374. {???????????? ??????????? ?????.
  375. ??? ? YA ? ? FB ??? Alter ??? Computed fields, ??????
  376. 1. ??????? ??????? ? ??????????? ?????.
  377. 2. ??????? ??? ???? ??????????? ????.
  378. 3. ????????? blr ?? ??????? ???? ? ??????.
  379. 4. ??????? ?????? ????.
  380. }
  381. procedure ReCreateComputedFields(ADataBase : TIBDataBase);
  382. var
  383. q1, q2: TIBSQL;
  384. Tr, ReadTr: TIBTransaction;
  385. begin
  386. q1 := TIBSQL.Create(nil);
  387. q2 := TIBSQL.Create(nil);
  388. Tr := TIBTransaction.Create(nil);
  389. ReadTr := TIBTransaction.Create(nil);
  390. try
  391. Tr.DefaultDatabase := ADataBase;
  392. q1.Transaction := Tr;
  393. ReadTr.DefaultDatabase := ADataBase;
  394. ReadTr.StartTransaction;
  395. q2.Transaction := ReadTr;
  396. q2.SQL.Text :=
  397. 'SELECT ' +
  398. ' F.RDB$COMPUTED_SOURCE AS COMPUTED_SOURCE, ' +
  399. ' RF.RDB$FIELD_NAME AS FIELD_NAME, ' +
  400. ' RF.RDB$RELATION_NAME AS TABLE_NAME ' +
  401. 'FROM ' +
  402. ' RDB$FIELDS F ' +
  403. ' JOIN RDB$RELATION_FIELDS RF ON RF.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME ' +
  404. ' JOIN RDB$RELATIONS R ON R.RDB$RELATION_NAME = RF.RDB$RELATION_NAME ' +
  405. 'WHERE ' +
  406. ' F.RDB$COMPUTED_SOURCE IS NOT NULL AND R.RDB$VIEW_SOURCE IS NULL';
  407. q2.ExecQuery;
  408. while not q2.EOF do
  409. begin
  410. Tr.StartTransaction;
  411. AddText('?????????????? ???? ' + q2.FieldByName('field_name').AsTrimString +
  412. ' ??????? ' + q2.FieldByName('table_name').AsTrimString);
  413. q1.SQL.Text :=
  414. 'ALTER TABLE "' + q2.FieldByName('table_name').AsTrimString +
  415. '" ALTER "' + q2.FieldByName('field_name').AsTrimString +
  416. '" COMPUTED BY ' + q2.FieldByName('computed_source').AsTrimString;
  417. q1.ExecQuery;
  418. q1.Close;
  419. Tr.Commit;
  420. q2.Next;
  421. end;
  422. q2.Close;
  423. ReadTr.Commit;
  424. finally
  425. q1.Free;
  426. q2.Free;
  427. Tr.Free;
  428. ReadTr.Free;
  429. end;
  430. end;
  431. procedure ReCreateView(ADataBase : TIBDataBase);
  432. var
  433. q1, q2: TIBSQL;
  434. Tr, ReadTr: TIBTransaction;
  435. function GetViewText(const FSQL: TIBSQL; const ReadTr: TIBTransaction): String;
  436. var
  437. S: String;
  438. ibsql: TIBSQL;
  439. begin
  440. ibsql := TIBSQL.Create(nil);
  441. try
  442. S := '';
  443. ibsql.Transaction := ReadTr;
  444. ibsql.SQL.Text := 'SELECT * FROM rdb$relation_fields ' +
  445. ' WHERE rdb$relation_name = :rn ORDER BY rdb$field_position ';
  446. ibsql.ParamByName('rn').AsString := FSQL.FieldByName('RDB$RELATION_NAME').AsTrimString;
  447. ibsql.ExecQuery;
  448. if not ibsql.EOF then
  449. begin
  450. while not ibsql.EOF do
  451. begin
  452. S := S + ibsql.FieldByName('rdb$field_name').AsTrimString + ','#13#10;
  453. ibsql.Next;
  454. end;
  455. SetLength(S, Length(S) - 3);
  456. end;
  457. finally
  458. ibsql.Free;
  459. end;
  460. Result :=
  461. Format('ALTER VIEW "%s" '#13#10 +
  462. ' ('#13#10, [FSQL.FieldByName('RDB$RELATION_NAME').AsTrimString]) +
  463. S + #13#10') '#13#10' AS ' +
  464. FSQL.FieldByName('RDB$VIEW_SOURCE').AsString;
  465. end;
  466. begin
  467. q1 := TIBSQL.Create(nil);
  468. q2 := TIBSQL.Create(nil);
  469. Tr := TIBTransaction.Create(nil);
  470. ReadTr := TIBTransaction.Create(nil);
  471. try
  472. Tr.DefaultDatabase := ADataBase;
  473. q1.Transaction := Tr;
  474. ReadTr.DefaultDatabase := ADataBase;
  475. ReadTr.StartTransaction;
  476. q2.Transaction := ReadTr;
  477. q2.SQL.Text :=
  478. 'SELECT R.RDB$RELATION_NAME, R.RDB$VIEW_SOURCE ' +
  479. 'FROM RDB$RELATIONS R ' +
  480. 'WHERE R.RDB$VIEW_SOURCE IS NOT NULL ';
  481. q2.ExecQuery;
  482. while not q2.EOF do
  483. begin
  484. Tr.StartTransaction;
  485. AddText('?????????????? ????????????? ' + q2.FieldByName('RDB$RELATION_NAME').AsTrimString);
  486. q1.SQL.Text := GetViewText(q2, ReadTr);
  487. q1.ExecQuery;
  488. q1.Close;
  489. Tr.Commit;
  490. q2.Next;
  491. end;
  492. q2.Close;
  493. ReadTr.Commit;
  494. finally
  495. q1.Free;
  496. q2.Free;
  497. Tr.Free;
  498. ReadTr.Free;
  499. end;
  500. end;
  501. end.