用FireDAC连MariaDB, FDConnection已经设置了CharacterSet=UTF8 用FDQuery查询一个自建的ACCOUNT表 SELECT NAME FROM ACCOUNT 能够返回有中文的记录,比如"中国" 但是用 SELECT NAME FROM ACCOUNT WHERE NAME='中国' 就返回空记录
Running script [Main] ... SELECT NAME FROM ACCOUNT NAME ---------- admin 鲨鱼
2 rows selected. [00:00:00.016]. Script [Main] finished without errors [00:00:00.016].
Running script [Main] ... SELECT NAME FROM ACCOUNT WHERE NAME='ADMIN' NAME ---------- admin
1 row selected. [00:00:00.000]. Script [Main] finished without errors [00:00:00.000].
Running script [Main] ... SELECT NAME FROM ACCOUNT WHERE NAME='鲨鱼' no rows selected. [00:00:00.000]. Script [Main] finished without errors [00:00:00.016].
----------------------------------------------
-
跟踪了一下代码,应该是FDQuery.Open或者ExecSQL的时候,对Params的类型判断出了问题,比如 var vName:string:='中国'; FDQuery.Open('SELECT * FROM ACCOUNT WHERE NAME=:1',[vName]) 因为没有显性的指定数据类型,系统给了一个缺省值空数组[]传递给了Params.DataType 改成 FDQuery.Open('SELECT * FROM ACCOUNT WHERE NAME=:1',[vName],[ftWideString])就可以了
----------------------------------------------
-
代码里没有用ParamByName('xxx').asXXXX的写法, 图省事用的类似于 FDQuery.Open('SELECT * FROM WORK_ORDER WHERE NAME=:1 LIMIT 1', [PWorkOrder.IDName], [ftWideString]); 如果IDName中没有中文字符, 不指定[ftWideString], FDQuery.Open('SELECT * FROM WORK_ORDER WHERE NAME=:1 LIMIT 1', [PWorkOrder.IDName]) 这样写也没问题, 说明FD在实现Open函数的时候已经对参数IDName的类型进行了内部判断,只是判断逻辑似乎忘记了ftWideString这档子事
另外FD支持这样的写法,会自动判单开放数组的数据类型 FDQuery.open('select * from xx where A=:1 AND B=:2 AND C=:3',['abb',123,-234.5678]);
----------------------------------------------
-
dont forget that "Firedac" do your life more easy when using all its potencial!
for example: --> create a rule for "change" your Fields Data-Type when some "Data-Type" dont exists or you needs change for another type.
var MyMapRule: TFDMapRule; begin // Hierarchy: // 1) FDManager1.FormatOptions --> always exists "one hide FDManager" when using any FD_component or class in your project // 2) FDConnection1.FormatOptions; // 3) Datasets FireDAC // FDManager.FormatOptions.OwnMapRules := True; // valid for all descendents of FDManager -> FDConnection --> FD__Querys_or_Tables --> Updates, StoreProc, etc... // MyMapRule := FDConnection1.FormatOptions.MapRules.Add; // here, how to name the "rule mask": this works like "LIKE" keyword on SQL expression: // --> %abcdef ==> all fields ended with "abcdef" // --> %abcdef% ==> all fields that contains "abcdef" // --> abcdef% ==> all fields that start with "abcdef" // --> _a__b ==> all fields that have: 5 chars on length and 2nd char = "a", and 5th char = "b" // MyMapRule.NameMask := 'FieldName_On_Table'; // same "fieldname" in your table. // MyMapRule.NameMask := '%name%'; // MyMapRule.NameMask := '%na_e'; // // The TypeMask property is useful for the databases that support domain based types, such as ODBC, InterBase, Firebird, PostgreSQL,SQLite. // MyMapRule.TypeMask := 'domain type DOMAIN_NAME_IN_YOUR_TABLE'; // you can use as "NameMask" definitions above!!! // // now, the "SourceDataType" and "TargetDataType" will using the definition above for exchanging data-type of fields with rules above // MyMapRule.SourceDataType := dtAnsiString; // read all AnsiSTRINGs... MyMapRule.TargetDataType := dtWideString; // works like WideSTRINGs!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3