Использую БД SQLite3 и компонент DBGrid для отображения данных. Заметил следующую проблему: если SELECT запрос осуществляется не к реальной таблице, а к виду, то при добавлении новой записи не отображается значение в тех полях, которые не были явно заполнены при добавлении записи (в примере ниже это id и calc_field), пока не вызовешь Refresh() для SQLQuery или не запустишь программу ещё раз. Как это можно исправить?
Форма:
- Код: Выделить всё
object Form1: TForm1
Left = 272
Height = 240
Top = 142
Width = 320
Caption = 'Form1'
ClientHeight = 240
ClientWidth = 320
OnCreate = FormCreate
LCLVersion = '2.0.12.0'
object DBGrid1: TDBGrid
Left = 0
Height = 215
Top = 0
Width = 320
Align = alClient
Color = clWindow
Columns = <>
DataSource = DataSource1
TabOrder = 0
end
object Button1: TButton
Left = 0
Height = 25
Top = 215
Width = 320
Align = alBottom
Caption = 'Добавить'
OnClick = Button1Click
TabOrder = 1
end
object DataSource1: TDataSource
DataSet = SQLQuery1
Left = 48
Top = 72
end
object SQLQuery1: TSQLQuery
FieldDefs = <>
Database = SQLite3Connection1
Transaction = SQLTransaction1
SQL.Strings = (
''
)
Params = <>
Left = 56
Top = 136
object SQLQuery1id: TAutoIncField
DisplayLabel = 'ИД'
DisplayWidth = 5
FieldKind = fkData
FieldName = 'id'
Index = 0
LookupCache = False
ProviderFlags = [pfInUpdate, pfInWhere]
ReadOnly = False
Required = False
end
object SQLQuery1name: TStringField
DisplayLabel = 'Имя'
DisplayWidth = 7
FieldKind = fkData
FieldName = 'name'
Index = 1
LookupCache = False
ProviderFlags = [pfInUpdate, pfInWhere]
ReadOnly = False
Required = False
end
object SQLQuery1calc_field: TStringField
DisplayLabel = 'Вычисляемое поле'
DisplayWidth = 13
FieldKind = fkData
FieldName = 'calc_field'
Index = 2
LookupCache = False
ProviderFlags = [pfInUpdate, pfInWhere]
ReadOnly = False
Required = False
end
end
object SQLTransaction1: TSQLTransaction
Active = True
Database = SQLite3Connection1
Left = 168
Top = 72
end
object SQLite3Connection1: TSQLite3Connection
Connected = True
LoginPrompt = False
DatabaseName = 'database.db'
KeepConnection = False
Transaction = SQLTransaction1
AlwaysUseBigint = False
Left = 168
Top = 136
end
end
Код:
- Код: Выделить всё
procedure TForm1.FormCreate(Sender: TObject);
begin
// Создаём таблицу
SQLQuery1.SQL.Text:='create table if not exists t (id INTEGER PRIMARY KEY, name VARCHAR)';
SQLQuery1.ExecSQL;
// Создаём вид с одним вычисляемым полем
SQLQuery1.SQL.Text:='CREATE VIEW if not exists v AS SELECT *, t.id || "-" || t.name AS calc_field FROM t;';
SQLQuery1.ExecSQL;
// Позволяем добавлять данные через вид
SQLQuery1.SQL.Text:='CREATE TRIGGER if not exists "" INSTEAD OF INSERT ON v ' +
'BEGIN ' +
'INSERT INTO t (name) VALUES (NEW.name); ' +
'END;'
;
SQLQuery1.ExecSQL;
// Выбираем все строки для DBGrid-а
SQLQuery1.SQL.Text:='select * from v';
SQLQuery1.Active:=True;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Str: String;
begin
if InputQuery('', 'Введите имя', Str) then
begin
SQLQuery1.Append;
SQLQuery1.FieldByName('name').AsString:=Str;
SQLQuery1.Post;
SQLQuery1.ApplyUpdates;
SQLTransaction1.CommitRetaining;
end;
end;
Демо: