简体   繁体   English

Delphi Firedac - FieldName 问题

[英]Delphi Firedac - FieldName issue

I migrate my application (Delphi 10.3) with MS Access base from ADODB to Firedac.我将带有 MS Access 基础的应用程序(Delphi 10.3)从 ADODB 迁移到 Firedac。 I have a problem with some TField FieldName when it has a complex name : Simple example: CREATE TABLE TEST ([SE_NAME] CHAR(3))当某些 TField FieldName 具有复杂名称时,我遇到了问题:简单示例: CREATE TABLE TEST ([SE_NAME] CHAR(3))

On a query like SELECT * FROM TEST T1 LEFT JOIN TEST T2 ON T1.SE_NAME=T2.SE_NAME在像SELECT * FROM TEST T1 LEFT JOIN TEST T2 ON T1.SE_NAME=T2.SE_NAME

I expect FieldNames :'T1.SE_NAME' and 'T2.SE_NAME' (like in Access 2013).我期望 FieldNames :'T1.SE_NAME' 和 'T2.SE_NAME' (就像在 Access 2013 中一样)。

With a ADODB TADOQuery :使用 ADODB TADOQuery :

  var f: TField;
  var s: string := '';
  for f in Query.Fields do
    s := s +  f.FieldName + ' ;' ;

s is 'T1.SE_NAME ;T2.SE_NAME ;' s'T1.SE_NAME ;T2.SE_NAME ;' OK.行。

With a Firedac TFDQuery :使用 Firedac TFDQuery :

  var f: TField;
  var s: string := '';
  for f in Query.Fields do
    s := s +  f.FieldName + ' ;' ;

s is 'SE_NAME ;SE_NAME_1 ;' s'SE_NAME ;SE_NAME_1 ;' : Not OK : FireDac changes the columns names. : 不正常 : FireDac 更改列名称。

How to keep, (with Firedac options ?) , the real columns names, without changing the SQL query (for compatibily needs) ?如何保留(使用 Firedac 选项?)真正的列名,而不更改 SQL 查询(为了兼容需要)?

In MSAccess (2013) the result of SELECT * FROM TEST T1 LEFT JOIN TEST T2 ON T1.SE_NAME=T2.SE_NAME is :在 MSAccess (2013) 中SELECT * FROM TEST T1 LEFT JOIN TEST T2 ON T1.SE_NAME=T2.SE_NAME是: 查询结果

Note that :注意 :

  • I know how to use queries, aliases... but I need to keep the queries for compatibility.我知道如何使用查询、别名……但我需要保留查询以确保兼容性。
  • The queries are just examples (not the real queries).查询只是示例(不是真正的查询)。

This is known as technical dept : you made decisions in the past which you considered fine, and now it proves to cause more damage than if you would have chosen differently (and at lower costs) in the past.这被称为技术部门:您过去做出了您认为很好的决定,现在证明它造成的损害比您过去选择不同(以更低的成本)的方式造成的损失更大。

SELECT * FROM test JOIN test immediately raises questions: SELECT * FROM test JOIN test立即提出问题:

  • Why is the same table joined against itself?为什么同一个表与自己连接? This rarily makes sense.这很少是有道理的。
  • Are really all columns needed?真的需要所有列吗? This is rarily efficient.这是非常有效的。

You should overcome your design decisions and fix it:你应该克服你的设计决定并修复它:

  • Select only those columns you actually need.选择您实际需要的那些列 No matter how many columns the table has.无论表有多少列。 This also helps avoiding ambiguity when tracking down issues (while helping performance in general).这也有助于在跟踪问题时避免歧义(同时有助于总体性能)。

  • Use aliases to exactly get the results you want:使用别名来准确地得到你想要的结果:

    • If you want t1.column as a column name in the results then define that thru SELECT t1.column AS "t1.column" (Ansi SQL, most DBMSs support this).如果您希望t1.column作为结果中的列名,则通过SELECT t1.column AS "t1.column" (Ansi SQL,大多数 DBMS 支持这一点)定义它。
    • MS Access needs square brackets and does not allow dots in aliases (the error message says "punctuation" but ie comma and colon are fine), so you have to come up with your own logic, ie underscores: SELECT t1.column AS [t1_column] . MS Access需要方括号,并且不允许在别名中使用点(错误消息说“标点符号”,但逗号和冒号都可以),因此您必须提出自己的逻辑,即下划线: SELECT t1.column AS [t1_column] Or just use a distinctive alias right away.或者直接使用一个独特的别名。

    If you leave it undefined you cannot expect there are no surprises (FireDAC surely wants to help you with the underscored suffix, as otherwise it would just overwrite existing matches).如果你不定义它,你不能指望没有任何惊喜(FireDAC 肯定想帮助你处理带下划线的后缀,否则它只会覆盖现有的匹配项)。 Just try out SELECT 1+ 1* 2 FROM table in different DBMSs and see which result column name that generates - I wonder how you prepare accessing that without using a column alias.只需在不同的 DBMS 中尝试SELECT 1+ 1* 2 FROM table并查看生成的结果列名称 - 我想知道您如何准备在不使用列别名的情况下访问它。

  • You can even select the same column from the same table multiple times: SELECT column AS c1, column+ 2021 AS c2 FROM test , yet you expect that to magically work out without using aliases?您甚至可以多次从同一个表中选择同一列: SELECT column AS c1, column+ 2021 AS c2 FROM test ,但您希望在不使用别名的情况下神奇地解决问题吗? Just use them - don't let it go undefined.只需使用它们 - 不要让它未定义。 In doubt do SELECT name AS name FROM test AS t (and even then it's not entirely sure if the resulting column name becomes name or NAME - that's why you should use quotation marks around your alias).有疑问做SELECT name AS name FROM test AS t (即使这样也不能完全确定生成的列名是name还是NAME - 这就是为什么你应该在别名周围使用引号)。

  • If you want to mix SELECT * FROM with Query.Fields.Fieldname to get a list of column names one table could have then do it per table instead of throwing multiple tables into the query.如果您想将SELECT * FROMQuery.Fields.Fieldname混合使用以获取一个表可能具有的列名列表,那么每个表都可以这样做,而不是将多个表放入查询中。 And even this approach is not good - rather consult the DBMS information schema - in FireDAC there are Get*Names() methods for that .甚至这种方法也不好 - 而是咨询 DBMS 信息模式 - 在 FireDAC 中有Get*Names()方法

Cross linking FireDAC adding underscore and SQL select join: is it possible to prefix all columns as 'prefix.*'?交叉链接FireDAC 添加下划线SQL 选择连接:是否可以将所有列作为“prefix.*”前缀?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM