Использую БД 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;
Демо:



