Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Редактирование данных из View'хи / 25 сообщений из 33, страница 1 из 2
10.08.2020, 09:41
    #39988055
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
В БД имеется некоторое комплексное представление (view), которое отображает много данных из разных таблиц.
В приложении его содержимое отображается через DBGrid. Хотелось бы иметь возможность редактирования данных при помощи grid inplace editor'а. Но т.к. источник вьюха, то вставлять изменённые данные обратно в таблицу нужно через какой-нибудь обработчик событий, который, в зависимости от того какие данные изменены, будет изменять соотв. таблицы или вообще вызывать ХПшки.

Вопрос: кто-нибудь уже делал такое? Это как-нибудь реализуемо без ковыряния DBGrid и создания наследников?
...
Рейтинг: 0 / 0
10.08.2020, 09:46
    #39988056
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
Такой механизм реализован в одних компонентах доступа и не реализован в других.
В общем случае, самое простое решение - загрузить данные в MemoryDataset (TClientDataset, TrxMemoryData, TdxMemTable) и вручную отсылать нужные запросы, при изменении данных
...
Рейтинг: 0 / 0
10.08.2020, 09:52
    #39988057
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
DimaBr
Такой механизм реализован в одних компонентах доступа и не реализован в других.
В общем случае, самое простое решение - загрузить данные в MemoryDataset (TClientDataset, TrxMemoryData, TdxMemTable) и вручную отсылать нужные запросы, при изменении данных

Компоненты доступа - FireDac.

А в TClientDataset (и прочих) предусмотрена возможность перехвата данных при изменении?
...
Рейтинг: 0 / 0
10.08.2020, 10:07
    #39988066
ma1tus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp
FireDac
У него, в датасете - отсутствует свойство наподобие SQLUpdate, где можно прописать вызов ХП или логику с if-ами?

Ну и в субд посмотри возможность создания триггеров / правил on view.
...
Рейтинг: 0 / 0
10.08.2020, 10:36
    #39988073
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp
А в TClientDataset (и прочих) предусмотрена возможность перехвата данных при изменении?

TDataset.AfterPost / BeforePost
TDataset.AfterInsert / BeforeInsert
TDataset.AfterDelete / BeforeDelete
и т.д.
...
Рейтинг: 0 / 0
10.08.2020, 11:25
    #39988088
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
DimaBr,

О, спасибо. Просто я почему-то думал что это в гриде надо перехватывать.
...
Рейтинг: 0 / 0
10.08.2020, 11:28
    #39988089
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp
DimaBr,

О, спасибо. Просто я почему-то думал что это в гриде надо перехватывать.
в гриде данных нет (С)
...
Рейтинг: 0 / 0
10.08.2020, 11:35
    #39988095
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
Firebird позволяет делать редактируемую вьюху на триггерах. Но если компонент внутри себя проверяет тип источника данных и самовольно выставляет ReadOnly, то упс.
...
Рейтинг: 0 / 0
10.08.2020, 11:50
    #39988103
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
Мимопроходящий
alekcvp
DimaBr,
О, спасибо. Просто я почему-то думал что это в гриде надо перехватывать.
в гриде данных нет (С)

Зато редактор данных там есть.
...
Рейтинг: 0 / 0
10.08.2020, 11:51
    #39988105
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
Fr0sT-Brutal
Firebird позволяет делать редактируемую вьюху на триггерах. Но если компонент внутри себя проверяет тип источника данных и самовольно выставляет ReadOnly, то упс.

О! А это как? Делать триггер BeforeXXXX? А в нем проверять какие поля изменились?
...
Рейтинг: 0 / 0
10.08.2020, 12:29
    #39988120
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvpА это как? Делать триггер BeforeXXXX?

Да.

alekcvpА в нем проверять какие поля изменились?

Да.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
10.08.2020, 12:46
    #39988138
vavan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp
в TClientDataset (и прочих) предусмотрена возможность перехвата данных при изменении?
смотря что под перехватом понимается
...
Рейтинг: 0 / 0
10.08.2020, 13:57
    #39988178
s62
s62
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp
В БД имеется некоторое комплексное представление (view), которое отображает много данных из разных таблиц.
В приложении его содержимое отображается через DBGrid. Хотелось бы иметь возможность редактирования данных при помощи grid inplace editor'а. Но т.к. источник вьюха, то вставлять изменённые данные обратно в таблицу нужно через какой-нибудь обработчик событий, который, в зависимости от того какие данные изменены, будет изменять соотв. таблицы или вообще вызывать ХПшки.

Вопрос: кто-нибудь уже делал такое? Это как-нибудь реализуемо без ковыряния DBGrid и создания наследников?
Не знаю, как в Firedac, а например в IBX запросы на update, insert, delete компонент TIBDataset генерирует (с твоей помощью) сам, но потом их можно редактировать вручную. Из моего опыта обычно редактировать приходилось. И там можно задать любой sql-запрос, единственное, значения параметров берутся из изменений в гриде и имена параметров соотносятся с именами полей в запросе select. Ситуация с View по-моему (может я что-то упускаю из виду) принципиально не отличается от ситуации, когда есть запрос на соединение из нескольких таблиц. (Сейчас глянул один свой запрос, там в select соединение нескольких таблиц и одного view, а обновления идут в одну таблицу).
В Firedac нет кастомных запросов на обновление, как есть в IBX?

P.S. извиняюсь, прочитал внимательней вопрос ТС, что нужно разную реакцию в разных случаях.
...
Рейтинг: 0 / 0
10.08.2020, 15:24
    #39988249
Vlad F
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp,

Тебе для какого сервера БД?
...
Рейтинг: 0 / 0
10.08.2020, 17:33
    #39988327
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
Vlad F
alekcvp,
Тебе для какого сервера БД?

Firebird же.
...
Рейтинг: 0 / 0
10.08.2020, 17:46
    #39988337
Vlad F
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp,
Дык, сделай в нем (замещающие) триггеры на обновление/удаление/вставку на этот свой VIEW и все заживет, даже в гриде.
Я такое вовсю практиковал, правда, на IBX. Но, как показывает опыт, FireDC местами ничем не хуже.))
...
Рейтинг: 0 / 0
10.08.2020, 20:48
    #39988405
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
Vlad F,

А там как-то потом надо выход обрабатывать из триггера или вьюхи просто игнорируют update'ы?
...
Рейтинг: 0 / 0
10.08.2020, 21:39
    #39988417
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp,

- в Firebird "выход из триггера" не обрабатывается никак. Триггер или срабатывает, или нет.

- про редактируемые view в Firebird - страница 145
https://firebirdsql.org/file/documentation/reference_manuals/firebird-language-reference-30-rus.pdf

- нет никаких "редактируемых гридов или датасетов" для SQL. Это фикция. В SQL есть чтение данных это select, и вставка,обновление удаление - это insert, update, delete. Никакими другими операциями или волшебством данные в SQL не модифицируются.

Соответственно, для "редактирования" датасет (не грид) должен уметь не просто генерировать insert/update/delete, но и позволять редактировать все эти три типа запросов на изменение данных. Причем, позволять не просто один запрос, а несколько, если view "составное" (в FB это можно сделать через execute block).
Например, если view выбирает данные из двух таблиц, то для "редактируемости" такого view в столбцах view должны быть идентификаторы записей обоих таблиц. Иначе нельзя будет сделать update. Соответственно, датасет в UpdateSQL должен позволять прописать там по 1 update для обоих таблиц (2 update).
...
Рейтинг: 0 / 0
11.08.2020, 10:54
    #39988530
L_argo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
Если имена полей в разных таблицах одинаковые, то можно попробовать указать имена ключевых полей и в БефореПост менять свойство UpdateTable.
ФайрДАК использует эти свойства для создания UPDATE-запросов.

Не пробовал, но может прокатить. И минимум изменений.
...
Рейтинг: 0 / 0
11.08.2020, 11:32
    #39988557
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
kdv,

Спасибо.
...
Рейтинг: 0 / 0
11.08.2020, 13:12
    #39988626
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
Ещё один вариант - научить cxTableView загружать данные из Dataset по именам колонок (имя колонки = имя View + '_' + Имя поля датасета)
Аналогичные события есть у cxTableView.DataController (OnAterDelete, OnAfterInsert, OnAfterPost)
...
Рейтинг: 0 / 0
11.08.2020, 16:33
    #39988701
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
DimaBr,

Я не использую девок.
...
Рейтинг: 0 / 0
11.08.2020, 19:26
    #39988744
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
С триггерами делал на Zeos, все прозрачно, никаких Sql не генерил. В TableName имя вьюхи и вперёд.
...
Рейтинг: 0 / 0
11.08.2020, 20:20
    #39988761
MaratIsk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp,

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
function BuildInsert(DataSet: TDataSet; TableName: string): string;
var
  s1, s2, s3 : string;
  i          : Integer;
  FieldName  : string;
begin
  for i := 0 to DataSet.Fields.Count -1 do begin
    FieldName := DataSet.Fields[i].FieldName;
    if not VarIsNull(DataSet.FindField(FieldName).Value) then begin
      s1 := s1 + FieldName + ', ';
      s2 := s2 + ':' + FieldName + ', ';
    end else begin
      s1 := s1 + FieldName + ', ';
      s2 := s2 + 'NULL, ';
    end; // if not VarIsNull(DataSet.Fields[i].Value)
  end; // for i := 0 to FieldList.Count
  SetLength(s1, Length(TRIM(s1))-1);
  SetLength(s2, Length(TRIM(s2))-1);
  s3 := 'INSERT INTO ' + TableName + ' (' + s1 + ') ' +
        'VALUES (' + s2 + ')';
  Result := s3;
end;



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
function BuildInsert(DataSet: TDataSet; TableName: string; FieldList: TStringList): string;
var
  s1, s2, s3 : string;
  i          : Integer;
  FieldName  : string;
begin
  for i := 0 to FieldList.Count -1 do begin
    FieldName := FieldList[i];
    if not VarIsNull(DataSet.FindField(FieldName).Value) then begin
      s1 := s1 + FieldName + ', ';
      s2 := s2 + ':' + FieldName + ', ';
    end else begin
      s1 := s1 + FieldName + ', ';
      s2 := s2 + 'NULL, ';
    end; // if not VarIsNull(DataSet.Fields[i].Value)
  end; // for i := 0 to FieldList.Count
  SetLength(s1, Length(TRIM(s1))-1);
  SetLength(s2, Length(TRIM(s2))-1);
  s3 := 'INSERT INTO ' + TableName + ' (' + s1 + ') ' +
        'VALUES (' + s2 + ')';
  Result := s3;
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.
function BuildUpdate(DataSet: TDataSet; TableName: string; KeyField: string): string;
var
  s1, s2, s3 : string;
  i          : Integer;
  FieldName  : string;
begin
  for i := 0 to DataSet.Fields.Count -1 do begin
    FieldName := DataSet.Fields[i].FieldName;
    if AnsiUpperCase(FieldName) <> AnsiUpperCase(KeyField) then begin
//      if DataSet.Fields[i].Value <> DataSet.Fields[i].NewValue then begin
        if not VarIsNull(DataSet.Fields[i].Value) then begin
          s1 := s1 + FieldName + '=:' +
                     FieldName + ', ';
        end else begin
          s1 := s1 + FieldName + '=NULL, ';
        end; // if not VarIsNull(DataSet.Fields[i].Value)
//      end; // if DataSet.FindField(FieldName).NewValue <>
    end; // if AnsiUpperCase(FieldName) <>
  end; // for i := 0 to FieldList.Count
  SetLength(s1, Length(TRIM(s1))-1);
  s3 := 'UPDATE ' + TableName + ' SET ' + s1 + ' ' +
        'WHERE ' + KeyField + '=:' + KeyField;
  if s1 = '' then
    Result := ''
  else
    Result := s3;
  Result := s3;
end;
...
Рейтинг: 0 / 0
11.08.2020, 20:23
    #39988764
MaratIsk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Редактирование данных из View'хи
alekcvp,

Код: 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.
function BuildUpdate(DataSet: TDataSet; Buffer: TDataSet; TableName: string;
  KeyField: string): string;
var
  s1, s2, s3 : string;
  i          : Integer;
  Field      : TField;
  FieldName  : string;
  iCount     : Integer;
begin
  iCount := 0;
  for i := 0 to DataSet.Fields.Count -1 do begin
    Field := DataSet.Fields[i];
    if Field.FieldKind = fkData then begin
      FieldName := Field.FieldName;
      if AnsiUpperCase(FieldName) <> AnsiUpperCase(KeyField) then begin
        if DataSet.Fields[i].Value <> Buffer.FindField(FieldName).Value then begin
          Inc(iCount);
          if not VarIsNull(DataSet.Fields[i].Value) then begin
            s1 := s1 + FieldName + '=:' +
                       FieldName + ', ';
          end else begin
            s1 := s1 + FieldName + '=NULL, ';
          end; // if not VarIsNull(DataSet.Fields[i].Value)
        end; // if DataSet.FindField(FieldName).NewValue <>
      end; // if AnsiUpperCase(FieldName) <>
    end; // if Field.FieldKind
  end; // for i := 0 to FieldList.Count
  SetLength(s1, Length(TRIM(s1))-1);
  s3 := 'UPDATE ' + TableName + ' SET ' + s1 + ' ' +
        'WHERE ' + KeyField + '=:' + KeyField;
  if iCount = 0 then s3 := '';
  Result := s3;
end;

...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Редактирование данных из View'хи / 25 сообщений из 33, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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