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

时间:2011-03-22 22:47:46

标签: delphi delphi-2010 firebird dbexpress

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

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

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

2 个答案:

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

答案 1 :(得分:0)

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