代码之家  ›  专栏  ›  技术社区  ›  mjn anonym

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

  •  9
  • mjn anonym  · 技术社区  · 15 年前

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

    4 回复  |  直到 8 年前
        1
  •  1
  •   Orhan Cinar    15 年前

    这是Felix Colibri的DFM解析器

    DFM Parser

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

    YACC

        2
  •  3
  •   robsoft    15 年前

    根据您使用的查询组件的类型,我想您可以在项目文件夹中使用命令行grep(或任何其他文本搜索工具)来完成这项工作。在dfm中,对于普通的类似tquery的组件,您将拥有

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

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

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

    考虑到这些字符串可以在dfm内部分布在多个“行”,以及考虑到可能需要检查的几个变体,我个人会写一小段delphi来完成这项工作。

    基本思想是:遍历给定目录中的所有文件/子文件夹,查找所有DFM文件,并将其读取到tstringlist中,检查您感兴趣的TQuery(等)SQL属性,并将结果(组件名、文件名、实际的SQL字符串)写入结果文件。真的最多不应该超过一两个小时。

    如果您已经存储了proc,并且使用了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中用一个开始和结束分隔开 和整个StringList内容本身包含在一对括号中。

    这有道理吗?还是我还缺什么?-)

        3
  •  0
  •   skamradt    15 年前

    因为dfm基本上是name=value格式,所以您可以将其加载到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
  •   mjn anonym    15 年前

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

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

    使用.po文件,可以很容易地从.pas文件中整理出所有sql.text,并在所有文件中整理出名称为“sql_…”的所有资源字符串。

    推荐文章