为什么 DBX 试图引用我的表名?

发布于 2024-10-25 16:36:08 字数 425 浏览 1 评论 0原文

我有一个连接到 Firebird 数据库的 TSimpleDataSet。数据集的内部数据集的 CommandType 设置为 ctTable,CommandText 设置为表名称。因此,我希望当我将其设置为 Active 时,它​​将生成一个类似于 select * from TableName 的查询。

相反,由于一些奇怪的原因,在 DB Express 代码内部的某个地方,它试图在表名周围加上引号,所以我最终得到 select * from "TableName",这当然会导致语法错误。显然,引号来自 TSqlConnection 的 Metadata 属性,该属性是只读的,因此我无法在代码中修复此问题。 (我想这太有意义了。)

有谁知道我该如何解决这个问题?

I've got a TSimpleDataSet connected to a Firebird database. The dataset's internal dataset's CommandType is set to ctTable, with CommandText set to a table name. So I expect, when I set it to Active, that it will generate a query that looks like select * from TableName.

Instead, for some bizarre reason, somewhere in the internals of the DB Express code it's trying to put quotes around the table name, so I end up with select * from "TableName", which of course causes syntax errors. Apparently the quotes are coming from the TSqlConnection's Metadata property, which is read-only, so I can't fix this in code. (That would make too much sense, I guess.)

Does anyone know how I can fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巷雨优美回忆 2024-11-01 16:36:09

引号可以确保名称可能与其他标识符冲突的表仍然可以使用。大多数数据库 - 不知道 FB - 允许将保留标识符用作对象名称,只要它们被引用即可,即 SELECT TIMESTAMP FROM X 可能不起作用,而 SELECT "TIMESTAMP" FROM X 可能起作用。 IIRC 这是一条 SQL-92 规则,允许在引入新关键字时向后兼容。
请注意,使用引用时,对象标识符可以(或必须,我不记得)区分大小写,因此,如果您有 INVOICE 表,则 select * from "invoice" 将不起作用,而 select * from "INVOICE “ 将要。

Quotes can ensure tables with names that can conflict with other identifiers can still be used. Most databases - don't know FB - allow reserved identifiers to be used as object names as long as they are quoted, i.e. SELECT TIMESTAMP FROM X may not work, while SELECT "TIMESTAMP" FROM X may. IIRC it's a SQL-92 rule to allow bakward compatibility if new keywords are introduced.
Be aware that when using quoted, the object identifiers can (or must, I don't remember) become case sensitive, thereby if you have the INVOICE table, select * from "invoice" won't work, while select * from "INVOICE" will.

金橙橙 2024-11-01 16:36:08

根据请求添加此解决方案。不过,不会将其标记为已接受,因为它感觉像是一个丑陋的黑客,如果可能的话,我想要一种更优雅的方法来防止该问题:

procedure RTTISurgery(connection: TSqlConnection);
var
  cls: TRttiType;
begin
  cls := TRttiContext.Create.GetType(connection.Metadata.ClassType);
  cls.GetField('FQuotePrefix').SetValue(connection.Metadata, '');
  cls.GetField('FQuoteSuffix').SetValue(connection.Metadata, '');
end;

注意:我不建议使用 RTTI 手术技术作为通用解决方案到编程问题。仅当没有更好的解决方案可用时才应使用它,因为它几乎总是涉及破坏封装。 (这就是使用它的意义:修复过度封装的错误的最后一搏解决方案。)

Adding this solution by request. Not going to mark it as accepted, though, because it feels like an ugly hack and if possible I'd like a more elegant way to prevent the problem:

procedure RTTISurgery(connection: TSqlConnection);
var
  cls: TRttiType;
begin
  cls := TRttiContext.Create.GetType(connection.Metadata.ClassType);
  cls.GetField('FQuotePrefix').SetValue(connection.Metadata, '');
  cls.GetField('FQuoteSuffix').SetValue(connection.Metadata, '');
end;

NOTE: I do not recommend the use of RTTI surgery techniques as a general purpose solution to programming problems. It should only be used when no better solution is available, since it almost invariably involves violating encapsulation. (Which is the point of using it: a last-ditch solution to fix over-encapsulated bugs.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文