powered by simpleCommunicator - 2.0.38     © 2025 Programmizd 02
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Неправильная кодировка прочитанного значения из sqlite базы
2 сообщений из 2, страница 1 из 1
Неправильная кодировка прочитанного значения из sqlite базы
    #38078271
vlad52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть sqlite база данных - описатель, содержащая список таблиц, список доменов, список полей, список ограничений (первичных и внешних ключей), список индексов. Я подключаюсь из Delphi XE3 c помощью встроенного компонента к этой базе. Есть отдельный модуль, в котором описанны классы TTableSpec, TFieldSpec, TConstraintSpec, TConstraintDetSpeс. Эти классы соответствуют записям вышеупомяноутой sqlite базы. В классах типа ТTableSpec есть такие поля типа FFields : TComponent, которое делается владельцем объектов типа TFieldSpec, также выгруженных из базы. После создания объектов путем чтения базы-описателя я обнаружил, что значения некоторых свойств объектов (например, TFieldSpec) находятся не в той кодировке(строка Edit2.Text:=TFieldSpec(TConstraintDetailSpec(TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).DetailList).FieldSpec).FieldName; в нижеприведенной функции проверки на то, что является поле первичным ключом данной таблицы).


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
	function TfmSettings.IsPrimaryKey(InputTableName : string; InputFieldName: string):Boolean;
	var
	  i : integer;
	  flag: boolean;
	begin
	  flag:=False;
	  for i:=0 to TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.ComponentCount-1 do
		begin
		  if ((TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).ConstraintType='PRIMARY') and (TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Fields.FindComponent(InputFieldName).Name=TConstraintDetailSpec(TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).DetailList).FieldName)) then
			flag:=True;
		  Edit1.Text:=TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).Name;
		  Edit2.Text:=TFieldSpec(TConstraintDetailSpec(TConstraintSpec(TTableSpec(DBSchema.Tables.FindComponent(InputTableName)).Constraints.Components[i]).DetailList).FieldSpec).FieldName;
		  Edit3.Text:=InputFieldName;
		end;
	  Result:=flag;
	end;


Привожу также код процедур, создающих объекты, связанных с неправильной кодировкой:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
	procedure CreationListOfFields(SQLConn: TSQLConnection; DBSchema : TDBSchemaSpec);
	var
	  NameField : TField;
	  PositionField : TField;
	  DescriptionField : TField;
	  CanInputField : TField;
	  CanEditField : TField;
	  ShowInGridField : TField;
	  ShowInDetailsField : TField;
	  IsMeanField : TField;
	  AutocalculatedField : TField;
	  RequiredField : TField;
	  Name1 : TField;
	  Name2 : TField;
	begin
		SQLConn.Execute('select f.id, f.position, f.name, f.description, f.can_input, '
		+' f.can_edit, f.show_in_grid, f.show_in_details, f.is_mean, f.autocalculated, f.required, t.name, d.name '
		+' from fields f left join tables t on f.table_id=t.id '
		+' left join domains d on f.domain_id=d.id order by t.name, d.name ', nil, results);
		if not results.IsEmpty then
		  begin
			results.First;
			Name1:=results.FieldByName('name_1');
			Name2:=results.FieldByName('name_2');
			lastTable:=Name1.AsString;
			TableSpec:=TTableSpec(DBSchema.Tables.FindComponent(lastTable));
			lastDomain:=Name2.AsString;
			DomainSpec:=TDomainSpec(DBSchema.Domains.FindComponent(lastDomain));
			NameField:=results.FieldByName('name');
			PositionField:=results.FieldByName('position');
			DescriptionField:=results.FieldByName('description');
			CanInputField:=results.FieldByName('can_input');
			CanEditField:=results.FieldByName('can_edit');
			ShowInGridField:=results.FieldByName('show_in_grid');
			ShowInDetailsField:=results.FieldByName('show_in_details');
			IsMeanField:=results.FieldByName('is_mean');
			AutocalculatedField:=results.FieldByName('autocalculated');
			RequiredField:=results.FieldByName('required');
			while not results.Eof do
			  begin
				if (Name1.AsString<>lastTable) then
				begin
				  lastTable:=Name1.AsString;
				  TableSpec:=TTableSpec(DBSchema.Tables.FindComponent(lastTable));
				end;
				if (Name2.AsString<>lastDomain) then
				begin
				  lastDomain:=Name2.AsString;
				  DomainSpec:=TDomainSpec(DBSchema.Domains.FindComponent(lastDomain));
				end;
				FieldSpec:=TFieldSpec.Create(TableSpec.Fields);
				FieldSpec.Setup( DomainSpec, PositionField.AsInteger,
				NameField.AsString, DescriptionField.AsString,
				FieldToBoolean(CanInputField),FieldToBoolean(CanEditField),
				FieldToBoolean(ShowInGridField), FieldToBoolean(ShowInDetailsField),
				FieldToBoolean(IsMeanField),FieldToBoolean(AutocalculatedField),
				FieldToBoolean(RequiredField));
				TComponent(FieldSpec).Name:=NameField.AsString;
				TableSpec.Fields.InsertComponent(FieldSpec);
				results.Next;
			  end;
		  end;
	end;

	procedure CreationListOfConstrAndConstrDet(SQLConn : TSQLConnection; DBSchema : TDBSchemaSpec);
	var
	IDField : TField;
	NameField : TField;
	ConstrTypeField : TField;
	ReferenceField : TField;
	UniqueKeyIdField : TField;
	HasValueEditField : TField;
	CascadingDeleteField: TField;
	ExpressionField : TField;
	NameField1 : TField;
	Name1 : TField;
	begin
		SQLConn.Execute('select c.id, c.name, constraint_type, reference, unique_key_id, has_value_edit, '
		+ 'cascading_delete, expression, t.name from constraints c left join tables t on c.table_id=t.id order'
		+' by t.name ', nil, results);
		if not results.IsEmpty then
		begin
		results.First;
		IDField:=results.FieldByName('ID');
		NameField:=results.FieldByName('name');
		ConstrTypeField:=results.FieldByName('constraint_type');
		ReferenceField:=results.FieldByName('reference');
		UniqueKeyIdField:=results.FieldByName('unique_key_id');
		HasValueEditField:=results.FieldByName('has_value_edit');
		CascadingDeleteField:=results.FieldByName('cascading_delete');
		ExpressionField:=results.FieldByName('expression');
		Name1:=results.FieldByName('name_1');
		lastTable:=Name1.AsString;
		TableSpec:=TTableSpec(DBSchema.Tables.FindComponent(lastTable));
		while not results.Eof do
		begin
		if (Name1.AsString<>lastTable) then
		begin
		  lastTable:=Name1.AsString;
		  TableSpec:=TTableSpec(DBSchema.Tables.FindComponent(lastTable));
		end;
		ConstraintSpec:=TConstraintSpec.Create(TableSpec.Constraints);
		ConstraintSpec.Setup(IDField.AsInteger,NameField.AsString, ConstrTypeField.AsString,
		ReferenceField.AsString, ConvertToInt(UniqueKeyIdField.AsString), FieldToBoolean(HasValueEditField),
		FieldToBoolean(CascadingDeleteField), ExpressionField.AsString);
		TComponent(ConstraintSpec).Name:=results.FieldByName('name').AsString;
		TableSpec.Constraints.InsertComponent(ConstraintSpec);
		SQLConn.Execute('select cd.id, f.name from constraint_details cd left join'
		+' fields f on f.id=cd.field_id where cd.constraint_id = '+inttostr(ConstraintSpec.ID), nil, results1);
		if not results1.IsEmpty then
		begin
		results1.First;
		NameField1:=results1.FieldByName('name');
		while not results1.Eof do
		begin
		 FieldSpec:=TFieldSpec(TableSpec.Fields.FindComponent(NameField1.AsString));
		 ConstDetSpec:=TConstraintDetailSpec.Create(ConstraintSpec.DetailList);
		 ConstDetSpec.Setup(NameField1.AsString, FieldSpec);
		ConstraintSpec.DetailList.InsertComponent(ConstDetSpec);
		results1.Next;
		end;
		end;
		results.Next;
		end;
		end;
	end;


P.S. SQL-запросы выполняются в sqlite нормально. Выдает нужные строки в нужной кодировке (по крайней мере визуально результат содержит читабельные английские и русские символы). Привожу также код классов:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
	unit DatabaseClasses;

	interface

	uses Classes;


	type
	TDataTypeId = (DataTypeId_String, DataTypeId_SmallInt, DataTypeId_Integer, DataTypeId_Word,
				   DataTypeId_Boolean, DataTypeId_Float, DataTypeId_Currency,
				   DataTypeId_BCD, DataTypeId_FmtBCD, DataTypeId_Date,
				   DataTypeId_Time, DataTypeId_DateTime, DataTypeId_TimeStamp,
				   DataTypeId_Bytes, DataTypeId_VarBytes, DataTypeId_Blob,
				   DataTypeId_Memo, DataTypeId_Graphic, DataTypeId_fmtMemo,
				   DataTypeId_FixedChar, DataTypeId_WideChar, DataTypeId_LargeInt,
				   DataTypeId_Array, DataTypeId_FixedWideChar, DataTypeId_WideMemo);

	TAlignSpec = (AlignSpec_Left, AlignSpec_Right, AlignSpec_Center);

	TFieldSpec=class;
	TConstraintDetailSpec = class;
	TIndexDetailSpec = class;

	TDBSchemaSpec=class(Tcomponent)
	  private
		FDomains: TComponent;
		FTables : TComponent;
	  public
		procedure Setup();
		destructor Destroy; override;
		property Domains: TComponent read FDomains;
		property Tables : TComponent read FTables;
	end;

	TDomainSpec = class(TComponent)
	  private
		FName: string;
		FDescription: String;
		FDataTypeId: TDataTypeId;
		FLength: Cardinal;
		FCharLength: Cardinal;
		FPrecision: Cardinal;
		FScale: Cardinal;
		FWidth: Word;
		FAlign: TAlignSpec;
		FShowNull: Boolean;
		FShowLeadNulls: Boolean;
		FThousandsSeparator: Boolean;
	  public
		procedure Setup(FName: string; FDescription: String; FDataTypeId: TDataTypeId;
		FLength: Cardinal;FCharLength: Cardinal;FPrecision: Cardinal;FScale: Cardinal;
		FWidth: Word;FAlign: TAlignSpec;FShowNull: Boolean;FShowLeadNulls: Boolean;
		FThousandsSeparator: Boolean);
		destructor Destroy; override;
		property Name: String read FName;
		property Description: String read FDescription;
		property DataTypeId: TDataTypeId read FDataTypeId;
		property Length: Cardinal read FLength;
		property CharLength: Cardinal read FCharLength;
		property Precision: Cardinal read FPrecision;
		property Scale: Cardinal read FScale;
		property Width: Word read FWidth;
		property Align: TAlignSpec read FAlign;
		property ShowNull: Boolean read FShowNull;
		property ShowLeadNulls: Boolean read FShowLeadNulls;
		property ThousandsSeparator: Boolean read FThousandsSeparator;
	  end;

	TTableSpec= class(TComponent)
	  private
		FFields : TComponent;
		FIndices: TComponent;
		FConstraints : TComponent;
		FName : string;
		FDescription: string;
		FCanAdd:  boolean;
		FCanEdit: boolean;
		FCanDelete: boolean;
	  public
		procedure Setup(FName : string; FDescription:string;
		FCanAdd:  boolean; FCanEdit: boolean; FCanDelete: boolean);
		destructor Destroy; override;
		property Description : string read FDescription;
		property Name : string read FName;
		property CanAdd:  boolean read FCanAdd;
		property CanEdit: boolean read FCanEdit;
		property CanDelete: boolean read FCanDelete;
		property Fields : TComponent read FFields;
		property Indices: TComponent read FIndices;
		property Constraints : TComponent read FConstraints;
	  end;

	TFieldSpec = class(TComponent)
	  private
		FDomainSpec: TDomainSpec;
		FPosition: integer;
		FFieldName: string;
		FDescription: string;
		FCanInput: boolean;
		FCanEdit: boolean;
		FShowInGrid: boolean;
		FShowInDetails: boolean;
		FIsMean: boolean;
		FAutoCalculated: boolean;
		FRequired: boolean;
	  public
		procedure Setup(FDomainSpec: TDomainSpec; FPosition: integer; FFieldName: string; FDescription: string; FCanInput: boolean; FCanEdit: boolean;
		FShowInGrid: boolean; FShowInDetails: boolean; FIsMean: boolean;FAutoCalculated: boolean;
		FRequired: boolean);
		destructor Destroy; override;
		property DomainSpec: TDomainSpec read FDomainSpec;
		property Position: integer read FPosition;
		property FieldName: string read FFieldName;
		property Description: string read FDescription;
		property CanInput: boolean read FCanInput;
		property CanEdit: boolean read FCanEdit;
		property ShowInGrid: boolean read FShowInGrid;
		property ShowInDetails: boolean read FShowInDetails;
		property IsMean: boolean read FIsMean;
		property AutoCalculated: boolean read FAutoCalculated;
		property Required: boolean read FRequired;
	 end;

	TConstraintSpec = class(TComponent)
	  private
		FID:  integer;
		FDetails: TComponent;
		FName: string;
		FConstraintType: string;
		FReference: string;
		FUniqueKeyId: integer;
		FHasValueEdit: boolean;
		FCascadingDelete: boolean;
		FExpression: string;
	  public
		procedure Setup(FID: integer; FName: string;
		FConstraintType: string; FReference: string; FUniqueKeyId: integer;
		FHasValueEdit: boolean; FCascadingDelete: boolean; FExpression: string);
		destructor Destroy; override;
		property ID: integer read FID;
		property Name: string read FName;
		property ConstraintType: string read FConstraintType;
		property Reference: string read FReference;
		property UniqueKeyId: integer read FUniqueKeyId;
		property HasValueEdit: boolean read FHasValueEdit;
		property CascadingDelete: boolean read FCascadingDelete;
		property Expression: string read FExpression;
		property DetailList: TComponent read FDetails;
	  end;

	TConstraintDetailSpec = class(TComponent)
	  private
		FFieldName: string;
		FFieldSpec: TFieldSpec;
	  public
		procedure Setup(FFieldName: string; FFieldSpec: TFieldSpec);
		destructor Destroy; override;
		property FieldName: string read FFieldName;
		property FieldSpec: TFieldSpec read FFieldSpec;
	  end;

	TIndexSpec = class(TComponent)
	  private
		FDetails: TComponent;
		FID : integer;
		FName: string;
		FUniqueness: boolean;
	  public
		procedure Setup(FID: integer; FName: string; FUniqueness: boolean );
		destructor Destroy; override;
		property ID : integer read FID;
		property DetailList:TComponent read FDetails;
		property Name: string read FName;
		property Uniqueness: boolean read FUniqueness;
	  end;

	TIndexDetailSpec = class(TComponent)
	  private
		FPosition: integer;
		FFieldSpec: TFieldSpec;
		FExpression: string;
		FDescend: boolean;
	  public
		procedure Setup(FPosition: integer; FFieldSpec: TFieldSpec;
		FExpression: string; FDescend: boolean  );
		destructor Destroy; override;
		property FieldSpec: TFieldSpec read FFieldSpec;
		property Position: integer read FPosition;
		property Expression: string read FExpression;
		property Descend: boolean read FDescend;
	  end;
	implementation

	procedure TDBSchemaSpec.Setup;
	begin
	  FDomains := TComponent.Create(self);
	  FTables := TComponent.Create(self);
	end;

	destructor TDBSchemaSpec.Destroy;
	begin
	  FDomains.Free;
	  FTables.Free;
	  inherited Destroy;
	end;

	procedure TDomainSpec.Setup;
	begin
	  self.FName:=FName;
	  self.FDescription:=FDescription;
	  self.FDataTypeId:=FDataTypeId;
	  self.FLength:=FLength;
	  self.FCharLength:=FCharLength;
	  self.FPrecision:=FPrecision;
	  self.FScale:=FScale;
	  self.FWidth:=FWidth;
	  self.FAlign:=FAlign;
	  self.FShowNull:=FShowNull;
	  self.FShowLeadNulls:=FShowLeadNulls;
	  self.FThousandsSeparator:=FThousandsSeparator;
	end;

	destructor TDomainSpec.Destroy;
	begin
	  inherited Destroy;
	end;

	procedure TTableSpec.Setup;
	begin
	  FFields := TComponent.Create(Self);
	  FConstraints := TComponent.Create(Self);
	  FIndices := TComponent.Create(Self);
	  Self.FName:=FName;
	  self.FDescription:=FDescription;
	  self.FCanAdd:=FCanAdd;
	  self.FCanEdit:=FCanEdit;
	  self.FCanDelete:=FCanDelete;
	end;

	destructor TTableSpec.Destroy;
	begin
	   FFields.Free;
	  FConstraints.Free;
	  FIndices.Free;
	  inherited Destroy;
	end;

	procedure TFieldSpec.Setup;
	begin
	  self.FDomainSpec:=FDomainSpec;
	  self.FPosition:=Fposition;
	  self.FFieldName:=FFieldName;
	  self.FDescription:=FDescription;
	  self.FCanInput:=FCanInput;
	  self.FCanEdit:=FCanEdit;
	  self.FShowInGrid:=FShowInGrid;
	  self.FShowInDetails:=FShowInDetails;
	  self.FIsMean:=FIsMean;
	  self.FAutoCalculated:=FAutoCalculated;
	  self.FRequired:=FRequired;
	end;

	destructor TFieldSpec.Destroy;
	begin
	  inherited Destroy;
	end;

	procedure TConstraintSpec.Setup;
	begin
	  FDetails := TComponent.Create(self);
	  self.FID:=FID;
	  self.FName:=FName;
	  self.FConstraintType:=FConstraintType;
	  self.FReference:=FReference;
	  self.FUniqueKeyId:=FUniqueKeyId;
	  self.FHasValueEdit:=FhasValueEdit;
	  self.FCascadingDelete:=FCascadingDelete;
	  self.FExpression:=FExpression;
	end;

	destructor TConstraintSpec.Destroy;
	begin
	  FDetails.Free;
	  inherited Destroy;
	end;


	procedure TConstraintDetailSpec.Setup;
	begin
	   self.FFieldName:=FFieldName;
	  self.FFieldSpec:=FFieldSpec;
	end;

	destructor TConstraintDetailSpec.Destroy;
	begin
	  inherited Destroy;
	end;


	procedure TIndexSpec.Setup;
	begin
	  FDetails := TComponent.Create(self);
	  self.FID:=FID;
	  self.FName:=FName;
	  self.FUniqueness:=FUniqueness;
	end;

	destructor TIndexSpec.Destroy;
	begin
	  FDetails.Free;
	  inherited Destroy;
	end;


	procedure TIndexDetailSpec.setup;
	begin
	  self.FPosition:=FPosition;
	  self.FFieldSpec:=FFieldSpec;
	  self.FExpression:=FExpression;
	  self.FDescend:=FDescend;
	end;

	destructor TIndexDetailSpec.Destroy;
	begin
	  inherited Destroy;
	end;
	end.


...
Рейтинг: 0 / 0
Неправильная кодировка прочитанного значения из sqlite базы
    #38078448
pit_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vlad52,

В XE3 впервые добавили dbExpress для SQLite, и он прилично глючит, лучше поискать сторонние компоненты,
dbExpress под SQLite точно был у Devart, а если не брать именно dbExpress то есть куча разных как платных так и бесплатных компонент, или ждать пока embarcadero допилит свой драйвер
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Неправильная кодировка прочитанного значения из sqlite базы
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]