1

我有一个连接到 Firebird 数据库的 TSimpleDataSet。数据集的内部数据集CommandType设置为ctTable,CommandText 设置为表名。所以我希望,当我将它设置为 Active 时,它​​会生成一个看起来像select * from TableName.

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

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

4

2 回答 2

2

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

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 手术技术作为编程问题的通用解决方案。只有在没有更好的解决方案可用时才应该使用它,因为它几乎总是涉及违反封装。(使用它的重点是:修复过度封装错误的最后解决方案。)

于 2011-03-23T18:04:36.023 回答
0

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

于 2011-03-23T09:53:44.560 回答