库解析SQL语句

时间:2009-12-04 15:44:20

标签: sql delphi parsing

我希望能够解析任意SQL SELECT语句并检索各种组件部分(列,关系,JOIN条件,WHERE条件,ORDER BY列),理想情况下使用Delphi。快速谷歌搜索显示了几种不同的免费软件产品,但目前尚不清楚它们是否完整和/或正在积极开发中。

我迫切需要提取一系列VIEW定义中使用的关系列表,以便在我尝试创建视图之前确保存在所需的视图或表。因此,例如,声明:

SELECT PersonID, LastName, OrderID 
FROM People P INNER JOIN Orders O ON P.PersonID = O.PersonID

我需要取回“人物”和“订单”这两个值。 (显然,这是一个简单的例子。我希望能够处理更复杂的情况,例如,单词“FROM”可能作为表达式的一部分出现在列列表中)。

我正在尝试在允许使用从DLL导出的STDCALL函数的数据库中提供此服务,因此理想情况下,任何候选库都可以从Delphi或C中调用。

3 个答案:

答案 0 :(得分:6)

看看Gold Parser.它有可用的Delphi版本,以及下载页面上的SQL语法。

答案 1 :(得分:0)

SQL解析器很复杂。

你有没有想过这样的方法:

  1. 开始交易。
  2. 将CREATE VIEW命令发送到服务器。
  3. 捕获错误(任何体面的数据库驱动程序都应该能够执行此操作)。
  4. 如果出现错误,请解析错误消息并向客户端显示缺少的表。
  5. 回滚
  6. 看这个例子(PostgreSQL):

    => begin;
    BEGIN
    => create view testview as select foo,bar from a join b on a.x=b.y;
    ERROR:  relation "a" does not exist
    LINE 1: create view testview as select foo,bar from a join b on a.x=...
                                                        ^
    => rollback;
    ROLLBACK
    

    或者这个(Oracle):

    SQL> create view testview as select foo,bar from a join b on a.x=b.y;
    create view testview as select foo,bar from a join b on a.x=b.y
                                                       *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    
    SQL> rollback;
    
    Rollback complete.
    

答案 2 :(得分:0)

您可以将Delphi与ADODB一起使用。

在没有真正打开记录集的情况下,使用TADOQuery来测试您的查询是否正常。您还可以检索查询的字段名称。

在表单上删除TADOConnection。 删除TMemo和TButton并尝试以下代码:

procedure TForm1.Button1Click(Sender: TObject);
var
  lADOQuery : TADOQuery;
  lFieldNames : TStrings;
begin
  lADOQuery := TADOQuery.Create(nil);
  try
    lADOQuery.Connection := ADOConnection1;
    lADOQuery.SQL.Text := Memo1.Text;
    lFieldNames := TStringList.create;
    try
      lADOQuery.GetFieldNames(lFieldNames);

      showmessage(lFieldNames.Text); // Show fieldNames of the query

      // To show that the dataset is not actually opened try this :
      // Throws an exception ( Dataset closed )
      //showmessage(inttostr(  lADOQuery.RecordCount ));
    except
      On e: Exception do
        ShowMessage('Invalid query');
    end;
    lFieldNames.free;
  finally
    lADOQuery.free;
  End;
end;