检索 TQuery 结果的元数据
在我们的应用程序中,用户可以输入 SQL 代码来从 NexusDB 数据库检索数据。 我们希望在不实际执行查询的情况下确定此类查询结果的元数据。我们使用元数据来确定字段的数量以及每个结果字段的数据类型。
[添加] 我们使用此功能作为用户定义的转换过程的一部分。实际的转换稍后会在类似批处理的过程中完成,但我们事先需要元数据,因此用户可以在转换中指定其他字段特征或修改,例如应用插件、创建父子关系等。 [/addition]
到目前为止,我们基本上通过将 WHERE FALSE
添加到 SQL 查询或用 WHERE FALSE AND
替换所有已存在的 WHERE
语句来实现此目的。但当然,我们必须解析整个 SQL 以确定要调整的正确 where 子句的确切位置,同时考虑注释、嵌套 SELECTS、JOIN 和其他子句。这样它变得非常复杂:-(
另一个缺点是,大多数时候查询的执行仍然需要很长时间,即使我们事先知道结果集将为空。
我们想知道是否有是实现此目的的另一种方法,
即 TQuery 对象必须有自己的解析器,将 SQL 语句拆分为不同的子句。如果我们可以在执行之前更改 where 子句,则不必自己进行解析。但是我们有点急于深入了解 TQuery 对象的内部结构,只是为了发现无法按照我们想要的方式使用它,
有人对此有什么建议吗?
In our application a user can enter SQL code to retrieve data from a NexusDB database.
We want to determine the metadata of the result of such a query without actually executing the query. We use the metadata to i.e. determine the number of fields and the datatype of each resulting field.
[addition]
We use this functionality as part of a user-defined conversion process. The actual conversion is done later on in a batch-like process, but we need the meta data beforehand, so the user can specify in the conversion additional field characteristics or modifications like applying plugins, creating parent-child relations, etc.
[/addition]
Until now we do this by basically adding WHERE FALSE
to the SQL query or replacing all already present WHERE
statements by WHERE FALSE AND
. But of course we have to parse the whole SQL to determine the exact location of the correct where clause to adjust, taking comments, nested SELECTS, JOINs and other clauses into account. Its getting quite complicated this way :-(
And another downside of this is, that most of the time the execution of the query can still take a long time, even though we know beforehand that the resultset will be empty.
We were wondering if there is another way of achieving this.
i.e. The TQuery object must have a parser of its own, splitting the SQL statement in its different clauses. If we could change the where clause just before execution, we wouldn't have to do the parsing ourselves. But we are a bit anxious of diving into the internals of the TQuery object, just to find out there is no way to use it the way we want to.
Anyone have any advise on this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您已经执行的操作的一个变体是将原始 SQL 语句放入嵌套 select 中,而不是修改 where 子句。
如果
select * from MyTable
是您的复杂查询,您可以像这样嵌入它以获得任何结果。我只在 SQL Server 中测试过这个,没有在 NexusDB 中测试过
A variant of what you already do is to put your original SQL statment in a nested select instead of modifying the where clause.
If
select * from MyTable
is your complicated query you can embed it like this to get no result.I have only tested this in SQL Server, not in NexusDB
深入研究客户端 TnxQuery 组件不会有帮助。它只是语句和游标句柄的包装。在客户端检索所需元数据的唯一方法是通过游标句柄。仅当执行查询时才会生成游标句柄。
目前,最小化执行查询时正在执行的工作的唯一方法就是您已经在做的事情。
如果您在我们的问题跟踪器中提交功能请求 ( http://www.nexusdb.com/mantis/ view_all_bug_page.php )我们可以研究指定一些标志来告诉引擎“永远不要处理任何数据”的可能性,而不需要搞乱查询本身。
Diving into the client-side TnxQuery component wouldn't help. It is only a wrapper around a statement and cursor handle. The only way to retrieve the metadata you are after on the client side is from the cursor handle. A cursor handle is only being produced when you execute the query.
For now the only way to minimize the work that is being performed when executing the query is what you are already doing.
If you file a feature request in our issue tracker ( http://www.nexusdb.com/mantis/view_all_bug_page.php ) we can research the possibility of specifying some flag to tell the engine to "never process any data" without the need of messing around with the query itself.
您还可以尝试将 TClientDataset 与 TDatasetProvider 链接到原始 TQuery(或任何 TDataset 后代)。然后将 TClientDataset 的 PacketRecords 属性设置为 0,并打开它。它将检索 TClientDataSet 中的字段,但不包含任何数据。
You can also try to link a TClientDataset with a TDatasetProvider to the original TQuery (Or any TDataset descendant). Then set the PacketRecords property of the TClientDataset to 0, and open it. It will retrieve the fields in the TClientDataSet, without any data.