我有一个连接到Firebird数据库的TSimpleDataSet。数据集的内部数据集CommandType
设置为ctTable
,CommandText设置为表名。所以我希望,当我将其设置为Active时,它会生成一个类似于select * from TableName
的查询。
相反,由于某些奇怪的原因,在DB Express代码的内部某处,它试图在表名周围加上引号,所以我最终得到select * from "TableName"
,这当然会导致语法错误。显然,引号来自TSqlConnection的Metadata
属性,它是只读的,所以我无法在代码中解决这个问题。 (我觉得这太有道理了。)
有谁知道如何解决这个问题?
答案 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 “会。”