PDA

View Full Version : سوال: مشکل فارسی با Aurelius و FireDac و Firebird



hp1361
پنج شنبه 15 خرداد 1393, 21:55 عصر
با سلام

من تصمیم گرفتم از Aurelius در برنامه ام استفاده کنم. اما مشکلی که دارم اینه که علی رغم اینکه فیلد ها از نوع string تعریف میشوند(که در دلفی XE5 از نوع Unicode است) و در جدول Firebird همگه از نوع Varchar با Charset از نوع UTF8 تعریف میشوند اما زمانیکه اطلاعات فارسی ارسال میکنم همگی بصورت ؟؟؟؟؟ ذخیره میشوند!
این درحالیه که در زمانیکه از Aurelius استفاده نمیکردم مقدار پاس داده شده رو بصورت AsWideString ارسال میکنم و مشکلی پیش نمیامد

دوستان راه حلی دارند؟مشکل از کجاست؟ مربوط به FireDac میشه یا Firebird یا Aurelius؟

ممنون

hp1361
جمعه 16 خرداد 1393, 07:00 صبح
سلام

بانک اطلاعاتی رو تغییر دادم و از SQLite استفاده کردم مشکل مذکور ووجود نداشت و کلمات فارسی بدون مشکل در دیتابیس ذخیره شد.

البته باید اینو بگم که وقتی از SQLite استفاده میکنیم Aurelius مستقیما به فایل دیتابیس وصل میشه و از لایه کانکشن استفاده نمیکنه(مثلا از همون FDConnection با درایور SQLite)

آیا میشه نتیجه گرفت مشکل از FireDac هستش؟ چطور میشه مشکل رو حل کرد؟

hp1361
یک شنبه 18 خرداد 1393, 11:41 صبح
سلام

بعد از کلی کلنجار با FireDac به نتیجه ای نرسیدم.

لذا رفتم از FIBPlus استفاده کردم. خوشبختانه اطلاعات رو به درستی در دیتابیس ذخیره میکه و نمایش میده
البته در قیمت Plain text editor مربوط به IBExpert "مدیر ارشد" رو بصورت
مدیر ارشد
و در Unicode editor هم به درستی
مدیر ارشد
نمایش میده

لذا میشه نتیجه گرفت هر مشکلی هست در FireDac هست.
دوستان راه حلی ندارن. برادر عزیز عشایری، مشکل دست شما رو میبوسه

ممنون.

BORHAN TEC
دوشنبه 19 خرداد 1393, 17:32 عصر
سلام
با این توضیحاتی که دادید بعیده که FireDac یا Firebird یا Aurelius باگی در این خصوص داشته باشند. فکر می کنم یکی از تنظیمات را در FireDAC انجام نداده اید و اون هم تنظیم خاصیت CharacterSet=utf8 مربوط به کامپوننت FDConnection هست.
موفق باشید...

hp1361
سه شنبه 20 خرداد 1393, 01:00 صبح
سلام

تمام این موارد رو چک کردم اما نشد. UTF8,None,UNICODE_FSS و الی اخر

نسخه جدید Aurelius رو هم با XE6 تست کردم اما افاقه نکرد!

حتی MapRules رو هم تعریف کردم اما فرقی نکرد!

موندم پس چرا FIBPlus درست کار میکنه!

hp1361
سه شنبه 20 خرداد 1393, 10:52 صبح
سلام مجدد

دیروز از در انجمن FireDac سوال رو مطرح کردم و جواب دادن که اگر بدون استفاده از Aurelius اطلاعات به درستی ذخیره میشه، مشکل از تیم Aurelius هستش و سوال رو باید از اونا بپرسی!

منم مثل یه بچه خوب سوال رو از تیم پشتیبانی Aurelius پرسیدم و در پاسخ گفتند:



By default, string properties in Aurelius are mapping as regular (Ansi) Varchar types in database. You have two options to solve this (and force Aurelius to use NVarchar):

1. Declare properties as WideString instead of string

2. Change Aurelius global configuration (note that this will affect *all* properties declared as string):

TGlobalConfigs.GetInstance.MapStringToNationalChar := true;


یعنی یا باید پروپرتی رو از نوع WideString تعریف کنیم و یا اینکه در تنظیمات Global مربوط به Aurelius مشخص کنیم که تمام اطلاعات بجای VarChar بصورت NVARCHAR ذخیره بشوند.

اگر بخواهیم از این دو روش استفاده کنیم اونوقت نه در FireDac و نه در Firebird نباید نوع Character Set رو UTF8 انتخاب کنیم در غیر این صورت ارور


Cannot Transliterate character between Character Sets


با رعایت موارد فوق اطلاعات به درستی در جدول ذخیره و نمایش داده میشه . فقط موضوعی که قابل توجه است اینه که Charset و Collate در جدول بصورت ISO8859_1 تعیین شده!
آیا این مورد مشکلی بوجود خواهد آورد؟

ویرایش 1 :

علی رغم اینکه اطلاعات در IBExpert درست نمایش داده میشه. اما زمانیکه اطلاعات رو در DBGrid نمایش میدم کماکان کاراکترهای ناخوانا نمایش داده میشه!



ویرایش 2 :


یکی از تنظیمات ای که TMS اعلام کرده بود رو انجام دادم . نوع Character Set در FireDac رو NONE انتحاب نمودم. و نیز در قسمتMapRules از بخش FormatOption مربوط به FireDac تنظیمات زیر رو انجام دادم
SourceDataType=>dtAnsiString
TargetDataType=>dtWideString
و حالا اطلاعات به درستی در گرید دلفی نمایش داده میشود!

برای نمایش صحیح در IBExpert نیز باید در زمان ثبت دیتابیس مقدار Font Characters Set رو ARABIC_CHARSET انتخاب نمود.

فعلا این بهترین حالتی بود که بدست آوردم. اما هنوز نوع Collation , Character set در جدول UTF8 نیست و ISO8859_1 میباشد!

مشکل روش ویرایش دوم :
هرچند اطلاعات در گرید و IBExpert درست نمایش داده می شوند اما وقتی یک ShowMessage ساده میگیرم اطلاعات واکشی شده از دیتابیس عجق وجق! نمایش داده میشه که احتمالا همون AnsiString ست! و کلی دنگ و فنگ بعدی!

hp1361
دوشنبه 26 خرداد 1393, 08:54 صبح
سلام

تلاشمون برای استفاده از FireDac بهمراه Aurelius به جایی نرسید!

لذا سوییچ کردم به FIBPlus (بجای FireDac) و همه چیز به خوبی کار میکنه!

موفق باشیم

hp1361
سه شنبه 10 تیر 1393, 06:58 صبح
سلام مجدد به دوستان و آرزوی قبولی طاعات و عبادات

امروز بعد از سحر نشستم پای سیستم و با خودم گفتم نگاهی به کدهای Aurelius بندازم ببینم آیا چیزی ازش سردر میارم یا نه. که ناگهان متوجه یه چیزو در فایل Aurelius.Drivers.FireDac شدم!

تابعی یافتم بنام SetParams که حدس زدم وظیفه تعریف نوع ها در زمان استفاده از Aurelius رو به عهده داره. لذا نگاهی به همین تابع در Aurelius.Drivers.FIBPlus انداختم که بدرستی تا بحال کار میکرد و دیدم بله! نوع فیلد ها که بصورت پارامتر ارجاع داده می شود در این تابع تعریف میشوند!



procedure TFireDacStatementAdapter.SetParams(Params: TEnumerable<TDBParam>);
var
P: TDBParam;
Parameter: TFDParam;
begin
for P in Params do
begin
Parameter := FADQuery.ParamByName(P.ParamName);

Parameter.DataType := P.ParamType;
Parameter.Value := P.ParamValue;
end;
end;




procedure TFIBPlusStatementAdapter.SetParams(Params: TEnumerable<TDBParam>);
var
P: TDBParam;
Parameter: TFIBXSQLVAR;
Bytes: TBytesStream;
begin
for P in Params do
begin
Parameter := FFIBQuery.ParamByName(P.ParamName);
if VarIsNull(P.ParamValue) then
Parameter.Clear
else
begin
case P.ParamType of
ftString:
Parameter.AsString := P.ParamValue;
ftSmallint, ftInteger, ftWord:
Parameter.AsInteger := P.ParamValue;
ftBoolean:
Parameter.AsBoolean := P.ParamValue;
ftFloat:
Parameter.AsFloat := P.ParamValue;
ftCurrency:
Parameter.AsCurrency := P.ParamValue;
ftDate:
Parameter.AsDate := P.ParamValue;
ftTime, ftDateTime:
Parameter.AsDateTime := P.ParamValue;
ftBlob:
begin
Bytes := TBytesStream.Create(TUtils.VariantToBytes(P.ParamV alue));
try
if VarIsNull(P.ParamValue) or (Bytes.Size = 0) then
Parameter.Clear
else
Parameter.LoadFromStream(Bytes);
finally
Bytes.Free;
end;
end;
ftWideMemo:
Parameter.AsWideString := P.ParamValue;
ftMemo:
Parameter.AsString := P.ParamValue;
// ftGraphic: ;
// ftFmtMemo: ;
// ftParadoxOle: ;
// ftDBaseOle: ;
// ftTypedBinary: ;
// ftCursor: ;
ftFixedChar:
Parameter.AsString := P.ParamValue;
ftWideString:
Parameter.AsWideString := P.ParamValue;
ftLargeint:
Parameter.AsInt64 := P.ParamValue;
// ftADT: ;
// ftArray: ;
// ftReference: ;
// ftDataSet: ;
// ftOraBlob: ;
// ftOraClob: ;
// ftVariant: ;
// ftInterface: ;
// ftIDispatch: ;
// ftGuid: ;
ftTimeStamp:
Parameter.AsDateTime := P.ParamValue;
// ftFMTBcd: ;
ftFixedWideChar:
Parameter.AsWideString := P.ParamValue;
// ftOraTimeStamp: ;
// ftOraInterval: ;
ftLongWord:
Parameter.AsInt64 := P.ParamValue;
ftShortint, ftByte:
Parameter.AsInteger := P.ParamValue;
ftExtended:
Parameter.AsExtended := P.ParamValue;
// ftConnection: ;
// ftParams: ;
// ftStream: ;
// ftTimeStampOffset: ;
// ftObject: ;
ftSingle:
Parameter.AsFloat := P.ParamValue;
else
Assert(false, 'Data type parameter not supported in FIBPlus driver');
end;
end;
end;
end;


لذا کدها رو از Aurelius.Drivers.FIBPlus به Aurelius.Drivers.FireDac کپی کردم و دیدم حالا Aurelius فیلدها رو به درستی در بانک ذخیره میکنه، به درستی در IBExpert نمایش داده میشه و نیز در برنامه به درستی رکورد ها نمایش داده میشوند!

برای اینکه خیلی در Aurelius.Drivers.FireDac دستکاری نکرده باشم صرفا اونو به شکل زیر تغییر دادم


procedure TFireDacStatementAdapter.SetParams(Params: TEnumerable<TDBParam>);
var
P: TDBParam;
Parameter: TFDParam;
begin
for P in Params do
begin
Parameter := FADQuery.ParamByName(P.ParamName);
if((P.ParamType=ftString) or (P.ParamType=ftMemo) or (P.ParamType=ftFixedChar)) then
Parameter.AsWideString := P.ParamValue
else
begin
Parameter.DataType := P.ParamType;
Parameter.Value := P.ParamValue;
end;
end;
end;


دوستان در این خصوص نظری اگه دارند خوشحال خواهم شد