Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

как вычитать isert'ы, произошедшие в триггере одной из таблиц [D7, FB2.1]


TheEd ©   (2009-04-01 09:15:00) 

Уважаемые мастера!
Есть таблица А, при добавлении в неё записи в тригере АбифоИнсерт в таблицу Б вставляется ряд записей, связанных с таблицей А.
так вот трабл: без DB.Close / DB.Open не вижу изменений :(

использую fibPlus, у которого есть DefaultUpdateTransaction, пытался сделать CommitRetaining, но видимо изменения идут в контексте транзакции на сервере, и изменения хрен видны.

Как их увидеть не разрывая связь с базой?


Виталий Панасенко   (2009-04-02 11:26:00) [1]

Не знаю, что ты там химичил.. специально слепил БД из двух таблиц - все прекрасно отображается. могу пример на мыло выслать..:-)
/******************************************************************************/
/***          Generated by IBExpert 2009.01.16 02.04.2009 10:24:41          ***/
/******************************************************************************/

SET SQL DIALECT 3;

SET NAMES WIN1251;

CREATE DATABASE 'c:\fdb\tttt.fdb'
USER 'SYSDBA' PASSWORD 'dbnfkbr'
PAGE_SIZE 16384
DEFAULT CHARACTER SET WIN1251;

/******************************************************************************/
/***                               Generators                               ***/
/******************************************************************************/

CREATE SEQUENCE GEN_T1_ID;
CREATE SEQUENCE GEN_T2_ID;

/******************************************************************************/
/***                                 Tables                                 ***/
/******************************************************************************/

CREATE TABLE T1 (
   ID  BIGINT NOT NULL,
   D   DATE DEFAULT current_date
);

CREATE TABLE T2 (
   ID   BIGINT NOT NULL,
   IID  BIGINT NOT NULL,
   DT   TIMESTAMP DEFAULT current_timestamp
);

/******************************************************************************/
/***                              Primary Keys                              ***/
/******************************************************************************/

ALTER TABLE T1 ADD CONSTRAINT PK_T1 PRIMARY KEY (ID);
ALTER TABLE T2 ADD CONSTRAINT PK_T2 PRIMARY KEY (ID);

/******************************************************************************/
/***                                Triggers                                ***/
/******************************************************************************/

SET TERM ^ ;

/******************************************************************************/
/***                          Triggers for tables                           ***/
/******************************************************************************/

/* Trigger: T1_AI0 */
CREATE OR ALTER TRIGGER T1_AI0 FOR T1
ACTIVE AFTER INSERT POSITION 0
AS
declare variable I integer;
begin
 /* Trigger text */
 I = 1;
 while (I<5) do
  begin
    insert into t2
    (iid) values (new.id);
    I = I+1;
  end
end
^

/* Trigger: T1_BI */
CREATE OR ALTER TRIGGER T1_BI FOR T1
ACTIVE BEFORE INSERT POSITION 0
as
begin
 if (new.id is null) then
   new.id = gen_id(gen_t1_id,1);
end
^

/* Trigger: T2_BI */
CREATE OR ALTER TRIGGER T2_BI FOR T2
ACTIVE BEFORE INSERT POSITION 0
as
begin
 if (new.id is null) then
   new.id = gen_id(gen_t2_id,1);
end
^

SET TERM ; ^

/******************************************************************************/
/***                               Privileges                               ***/
/******************************************************************************/

/* Privileges of users */
GRANT SELECT ON RDB$FORMATS TO PUBLIC;
GRANT SELECT ON RDB$PAGES TO PUBLIC;
GRANT SELECT ON RDB$ROLES TO PUBLIC;


TheEd   (2009-04-01 19:17:00) [2]

2 Медвежонок Пятачок:

не спорю...
но перепахивать дизайн страшно некогда, а дурная натура пытается дойти до сути


Медвежонок Пятачок   (2009-04-01 19:09:00) [3]

кривой изначальный дизайн приложения неизбежно приводит к кривым решениям


TheEd   (2009-04-01 17:56:00) [4]

итак, сдела параметры транзакции:
 read_commited
 read
 no_rec_version
 wait

далее в коде, после того как вставились записи:
 SomeReadTransaction.CommitRetaining;
 SomeDataSet.FullRefresh;

и болт!:(((

короче вышел из ситуации но криво:
procedure TDM.FullReconnect;
var
 i : integer;
begin
 inherited;
 for i := 1 to dsContainer.DataSetCount - 1 do   // в контейнере - все датасеты
   with dsContainer.DataSet(i) do
     Tag := RecNo;

 fibDB.Close;  // это БД
 DoConnect;  // тут БД коннестится и датасеты все Оупенятся

 for i := 1 to dsContainer.DataSetCount - 1 do
   with dsContainer.DataSet(i) do
     RecNo := Tag; // восстанавливаем позиции
end;


Anatoly Podgoretsky   (2009-04-01 15:56:00) [5]

> TheEd  (01.04.2009 10:04:03)  [3]

Переделать архитектуру, что бы это было желательно или по крайней мере безразлично.


PEAKTOP   (2009-04-01 14:49:00) [6]

> хотя странно.. FullRefresh делает тотже CloseOpen. только
> старается оставить активной текущую позицию в НД


Вполне закономерно, если у читающей транзакции не указано свойство Params, то будут параметры по-умолчанию:
isc_tpb_concurrency
isc_tpb_write
isc_tpb_nowait

А надо поставить
isc_tpb_read_commited
isc_tpb_read
isc_tpb_rec_version или isc_tpb_no_rec_version (как надо автору)
isc_tpb_nowait или isc_tpb_wait (как надо автору)


Виталий Панасенко   (2009-04-01 10:54:00) [7]

хотя странно.. FullRefresh делает тотже CloseOpen. только старается оставить активной текущую позицию в НД


Виталий Панасенко   (2009-04-01 10:53:00) [8]

если 2 транзакции (читающая и Update), то для НД нужно указать AutoCommit=TRue, тогда после каждого изменения будет происходить commit для Update транзакции. но читающая будет открытой...
> TheEd   (01.04.09 10:04) [3]
>
>
> > завершить и начать снова читающую транзакцию
>
>  TA_read.Active := false;
>  TA_read.Active := true;
>
> если так (?) то все НД закроются, а этого крайне нежелательно.
>
>
>
> > тоже поможет FullRefresh..
>
> не помогает :(

тогда сделай  FIBDataSet.CloseOpen(False)


TheEd   (2009-04-01 10:19:00) [9]


> Желательнее нихрена не видеть?

чую носом что можно "не отрывая глаз" увидеть...


> А что такое тут DB? Если датасет так обозвал - то это нормально.

DB : TpFIBDataBase
и как нормально? :S


Sergey13   (2009-04-01 10:15:00) [10]

> [0] TheEd   (01.04.09 09:15)
> без DB.Close / DB.Open

А что такое тут DB? Если датасет так обозвал - то это нормально.


Медвежонок Пятачок   (2009-04-01 10:07:00) [11]

если так (?) то все НД закроются, а этого крайне нежелательно.

Желательнее нихрена не видеть?


TheEd   (2009-04-01 10:04:00) [12]


> завершить и начать снова читающую транзакцию

 TA_read.Active := false;
 TA_read.Active := true;

если так (?) то все НД закроются, а этого крайне нежелательно.


> тоже поможет FullRefresh..

не помогает :(


Виталий Панасенко   (2009-04-01 09:50:00) [13]


> TheEd   (01.04.09 09:15)  

а откуда НД таблицы Б знает о том, что триггер что-то вставил? абсолютно ничего не знает.. если это мастер-деталь, то сделать FullRefresh для Б. Да, в принципе, даже если не мастер-деталь, тоже поможет FullRefresh.. но если данных много.. сам понимаешь...


Медвежонок Пятачок   (2009-04-01 09:46:00) [14]

завершить и начать снова читающую транзакцию


Наверх

Титульная страница Поиск, карта сайта Написать письмо