【问题标题】:Library to parse SQL statements用于解析 SQL 语句的库
【发布时间】:2009-12-04 15:44:19
【问题描述】:

我希望能够解析任意 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 中调用。

【问题讨论】:

  • 您能告诉我您使用的是哪个 SQL 引擎吗?除非我错过了。
  • 很高兴,但这对您没有帮助。我正在使用 R:Base。

标签: sql delphi parsing


【解决方案1】:

看看Gold Parser.有Delphi版本,下载页面有SQL语法。

【讨论】:

  • 谢谢。这在我的谷歌搜索中没有出现,大概是因为 SQL 部分与解析器和 Delphi 提及的页面位于单独的页面上。
  • 是的,有点晦涩。不过系统不错。
  • 死链接。网站已关闭(“正在进行中。”)
【解决方案2】:

SQL 解析器很复杂。

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

  1. 开始交易。
  2. 向服务器发送 CREATE VIEW 命令。
  3. 捕捉错误(任何体面的数据库驱动程序都应该能够做到这一点)。
  4. 如果出现错误,解析错误消息并向客户端显示丢失的表。
  5. 回滚

查看这个例子(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

或者这个(甲骨文):

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.

【讨论】:

  • 是的,这就是我目前正在做的事情。但是,如果我可以在从原始数据库创建结构定义文件时检测到问题,我可以立即解决其中的一些问题(本质上,我正在尝试对数据库中的所有视图定义执行传递闭包,这不幸的是,DBMS 在提供视图列表时没有这样做)。
  • 哈。这绝对是一个 hack,但很有趣。不幸的是,张贴者并没有说他甚至有一个正在运行的数据库服务器可以使用。在尝试这样的事情之前,请确保您调查了潜在的威胁媒介!
  • 我认为没有数据库是正确的。你在我输入回复时发布了,拉里。 :)
  • 不,Dolph,您实际上是对的。我没有正在运行的服务器,我现在正在处理的问题涉及文件服务器类型的数据库。但问题很普遍,它不应该是特定于数据库的。
【解决方案3】:

您可以将 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;

【讨论】:

  • 无法使用 ADO 访问我的 DBMS。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 2011-05-02
  • 2021-06-03
相关资源
最近更新 更多