有没有一个工具可以从Delphi表单文件中提取所有SQL命令字符串?

时间:2010-03-25 06:26:24

标签: sql delphi extract dfm

对于文档和进一步检查,我想在许多项目中的所有DFM文件上运行“提取字符串”以查找所有SQL语句。是否有可以执行此操作的命令行工具? DFM文件都是文本格式。

5 个答案:

答案 0 :(得分:3)

根据您使用的查询组件的类型,我认为您可以使用项目文件夹中的命令行grep(或任何其他文本搜索工具)来执行此操作。在DFM中,对于普通的类似TQuery的组件,你将会有类似

的内容
   SQL.Strings=( 'select * from mytable' )

或者可能(我没有Delphi可以检查,在家里的乐趣!)

   SQL.Text=( 'select * from mytable' )

考虑到这些字符串如何在DFM内部的几个“行”上传播,并且考虑到您需要检查的几个变体,我个人会写一小段Delphi来执行此操作。

基本理念是;遍历给定目录中的所有文件/子文件夹,查找所有DFM文件,并为每个文件读入TStringList,检查您感兴趣的任何TQuery(etc)SQL属性,并编写结果(组件名称,文件名,实际SQL字符串)输出到结果文件。真的不应该超过一两个小时的工作。

如果你有使用TQuery类型组件以外的其他东西调用的存储过程,你必须首先查看DFM并看看SQL是如何出现的;

可能会有所不同
   CommandText=( 'exec mysproc :id, :value' )

编辑: 在评论中讨论之后,这是来自我的一个DFM的样本;

    (other properties)
    SQL.Strings = (
      'SELECT D.*, '
      'C.DESCRIPTION AS CLASS_DESCRIPTION, '
      'C.CHQ_NUM_THRESHOLD AS CLASS_CHQ_NUM_THRESHOLD,'
      'C.CREDIT_LIMIT AS CLASS_CREDIT_LIMIT,'
      'A.REF AS ACCOUNT_REF,'
      'A.SORT_CODE AS ACCOUNT_SORT_CODE,'
      'A.ACCOUNT_NUMBER AS ACCOUNT_ACCOUNT_NUMBER,'
      'A.PREFERRED_ACCOUNT AS ACCOUNT_PREFERRED_ACCOUNT'
      'FROM '
      'DRAWER_ACCOUNTS A LEFT JOIN DRAWERS D '
      'ON D.REF=A.DRAWER_REF'
      'LEFT JOIN REF_DRAWER_CLASSES C'
      'ON D.DRAWER_CLASS = C.CLASS_ID'
      'WHERE A.SORT_CODE=:PSORT AND A.ACCOUNT_NUMBER=:PACC')
    (other properties)

所以我真正需要做的就是找到SQL.Strings = (位,然后读取行的其余部分和所有后续行,删除前导和尾随',直到我到达一行以')'结束 - 此时我已经完成了。无论有趣的SQL(和注释)可能包含在每行的引号内都是无关紧要的。您想要阅读您感兴趣的每一行,并在每行的第一个和最后一个引号之间剪切文本。这必须起作用,因为我无法看到Delphi如何以任何其他方式自行传输,它不可能“读取”字符串内容 - 它只是基于字符串列表(可能)分成行和每行在DFM中以开放和结束'分隔,并且整个字符串列表内容本身包含在一对括号内。

这是否有意义,还是我仍然缺少某些东西? : - )

答案 1 :(得分:1)

这是Felix Colibri的DFM Parser

DFM Parser

这是一个有趣的工具,可以做这样的事情

YACC

答案 2 :(得分:1)

我创建了自己的DFM解析器,并使用RAD Studio和我所在公司的600个源文件进行了测试。解析器是用Go编写的。

https://github.com/gonutz/dfm

您可以使用它解析DFM文件并递归检查内存中对象,以查找dfm.String类型的属性。

答案 3 :(得分:0)

由于DFM基本上是名称=值格式,您只需加载到tStringlist,然后遍历每一行,查找您感兴趣的特定属性名称:

var
  slDfm : tStringList;
  Item : String;
  ix : integer;
begin
  slDFM := tStringlist.create;
  try
    slDFM.LoadFromFile( filename );
    for ix := 0 to slDfm.Count-1 do
      begin
        slDfm.Strings[ix] := Trim(slDfm.Strings[ix]);
        if SameText(Trim(slDfm.Names[ix]),'CommandText') then
          memo1.Lines.Add('"'+Trim(slDfm.ValueFromIndex[ix])+'"');
      end;
  finally
    slDFM.free;
  end;
end;

答案 4 :(得分:0)

非常感谢您的回答!我将尝试的另一个解决方案是“GNU Gettext for Delphi and C++ Builder”中包含的“提取字符串”工具。

.po文件不仅包括所有组件文本,还包括所有资源字符串(存储SQL命令的另一个地方),包括对原点的引用(pas或dfm文件,哪个组件属性名称),它是一个非常简单的“name = value”列表。

使用.po文件,可以很容易地从.pas文件中清除所有SQL.Text,并在所有文件中清除所有名称为“SQL _...”的资源字符串。