简体   繁体   中英

Delphi Firedac - FieldName issue

I migrate my application (Delphi 10.3) with MS Access base from ADODB to Firedac. I have a problem with some TField FieldName when it has a complex name : Simple example: 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

I expect FieldNames :'T1.SE_NAME' and 'T2.SE_NAME' (like in Access 2013).

With a 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 ;' OK.

With a 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 ;' : Not OK : FireDac changes the columns names.

How to keep, (with Firedac options ?) , the real columns names, without changing the SQL query (for compatibily needs) ?

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

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:

  • 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).
    • 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] . 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). 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.

  • 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? 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).

  • 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. And even this approach is not good - rather consult the DBMS information schema - in FireDAC there are Get*Names() methods for that .

Cross linking FireDAC adding underscore and SQL select join: is it possible to prefix all columns as 'prefix.*'?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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