Конференция "Базы" » Транзакции в триггере
 
  • sql (29.08.08 11:40) [0]
    ALTER TRIGGER [trgSettings] ON [dbo].[tSettings]
    AFTER INSERT, DELETE, UPDATE
    AS
    BEGIN
    BEGIN TRANSACTION
     DECLARE
       @IdSetting int,
       @Section nvarchar(32),
       @Ident nvarchar(32),
       @Value nvarchar(32),
       @iDate datetime,
       @iUser int,
       @uDate datetime,
       @uUser int,
       @Note nvarchar(255),
       @Now datetime,
       @i int;

     SET @Now = GETDATE();

     SET NOCOUNT ON;

     IF EXISTS(SELECT * FROM Inserted)
       BEGIN
         IF NOT EXISTS(SELECT * FROM Deleted)
           BEGIN
             ROLLBACK TRANSACTION
           END
         ELSE
           BEGIN
             COMMIT TRANSACTION
           END;
       END
     ELSE
       BEGIN
         COMMIT TRANSACTION
       END;
    END



    В какой части текста триггера лучше всего открывать глобальную, по отношению к триггеру, транзакцию ?
  • Игорь Шевченко © (29.08.08 11:41) [1]
    Транзакции в триггере есть безусловное зло :)
  • MsGuns © (29.08.08 11:43) [2]
    Как же все-таки гадость, этот ваш... триггер !
  • sql (29.08.08 11:53) [3]
    Ребят кому не сложно, можно ваши триггеры посмотреть, большей частью интересуют «сложно выпоенные» триггеры. Не беда если я в них не разберусь, просто хотелось посмотреть как их (триггеры) делают если можно так сказать профессионалы.

    Спасибо.
  • Polevi © (29.08.08 12:02) [4]
    профессионалы стараются избегать триггеров
  • sql (29.08.08 12:05) [5]

    > Polevi ©   (29.08.08 12:02) [4]

    А как же тогда логирование изменений, обеспечение целостности информации и т.д. ? Да, и насколько в среднем триггер замедляет процесс обработки данных ?
  • Игорь Шевченко © (29.08.08 12:08) [6]

    > А как же тогда логирование изменений, обеспечение целостности
    > информации и т.д.


    целостность информации обычно обеспечивается декларативными средствами.

    Про транзакции и триггеры рекомендую почитать:
    http://sql.ru/forum/actualthread.aspx?tid=588877 все страницы
  • stas © (29.08.08 12:09) [7]
    Для чего эта проверка?

    >
    >  IF EXISTS(SELECT * FROM Inserted)
    >    BEGIN
    >      IF NOT EXISTS(SELECT * FROM Deleted)
  • Ega23 © (29.08.08 12:09) [8]

    > профессионалы стараются избегать триггеров
    >


    +1.


    > А как же тогда логирование изменений, обеспечение целостности
    > информации и т.д. ?


    целостность данных обеспечивается средствами самой СУБД, такими как PK-FK constraints, нафига для этой цели триггеры - непонятно.

    Логгирование отлично обеспечивается из других мест (ХП, например).

    За 8+ лет работы с БД триггер понадобился один единственный раз.
  • Ega23 © (29.08.08 12:11) [9]

    > Для чего эта проверка?


    А как, по-твоему, устроена операция Update? Сначала Delete, потом Insert
  • stas © (29.08.08 12:13) [10]
    Ega23 ©   (29.08.08 12:11) [9]
    т.е. для определения операции?
  • sql (29.08.08 12:13) [11]

    > stas ©   (29.08.08 12:09) [7]

    В зависимости от события INSERT, UPDATE, DELETE, делать "разные вещи"...
  • stas © (29.08.08 12:17) [12]
    не проще 3 триггера сделать?
  • Ega23 © (29.08.08 12:21) [13]

    > т.е. для определения операции?


    Ну судя по тексту - да.
  • sql (29.08.08 12:22) [14]

    > stas ©   (29.08.08 12:17) [12]

    Мне кажется нет...
  • stas © (29.08.08 12:23) [15]
    Ну, или

    IF <Условие> --определяем UPDATE
    BEGIN
    Declare ...
    END

    IF <Условие> --INSERT
    BEGIN
    Declare ...
    END

    IF <Условие> -- DELETE
    BEGIN
    Declare ...
    END
    ...
    Insert into

    без всяких транзакций
  • sql (29.08.08 12:23) [16]

    > Ega23 ©   (29.08.08 12:21) [13]

    Не по тексту судить не надо, этот текст к примеру...
  • sql (29.08.08 12:25) [17]

    > stas ©   (29.08.08 12:23) [15]

    А допустим если необходимо при разных событиях иметь общию(ии) переменные...
  • stas © (29.08.08 12:30) [18]
    Вверху общие.

    Я сразу скажу этот лог (как в примере) работать будет некорректно при пакетной вставке, удалении обновлении.

    У нас огранизован лог подобный лог (я не настаиваю на его правильности)
    3 триггера на таблицу. Внутри просто
    Insert into...
    select f1..fn from inserted.
    Каждую ночь таблицы LOG списываются в архив и очищаются, т.к. при наполнении таблицы лога вставка происходит все медленее.
  • Игорь Шевченко © (29.08.08 12:49) [19]

    > А как, по-твоему, устроена операция Update? Сначала Delete,
    >  потом Insert


    а почему не наоборот ?
  • Palladin © (29.08.08 12:52) [20]
    из-за ключёв я думаю :)
  • MsGuns © (29.08.08 12:54) [21]
    Следует триггеры воспринимать лишь как дополнительное средство программирования НА СТОРОН СЕРВЕРА и не более того. Дополнительное.
    В клиент-серверных системах существует, грубо говоря, две "крайние" концепции построения логики:
     чисто клиентская, когда сервер занимается только исполнением запросов от клиента с минимумом "самостоятельности", контроль же за целостностью данных, учет реплик, "сервисные" функции и т.д. остаются на "совести" клиента
      и
    чисто серверная, когда максимум алгоритмов реализуются самим сервером, клиент же лишь обращается к набору "макро"-функций, зачастую даже не имея представления о физическом представлении данных на сервере и не неся ответственности ни за целостность данных, ни за их полноту и корректность

    В каждом конктретном случае применяется собственная "средняя" концепция, заключающаяся в некоей комбинации этих двух концепций. Причем очень часто текущая концепция модели со временем постепенно транформируются от первой крайности ко второй или наоборот. Не зная предметной области и поставленных перед разработчиком СУБД задач, невозможно советовать. Это все равно, что тащить в операционную больного, не удосужившись хотя бы спросить у него, где болит ;)
  • DiamondShark © (29.08.08 13:28) [22]

    >  чисто клиентская, когда сервер занимается только исполнением
    > запросов от клиента с минимумом "самостоятельности", контроль
    > же за целостностью данных, учет реплик, "сервисные" функции
    > и т.д. остаются на "совести" клиента

    Нет такой "концепции".
    Это называется "всю жизнь лабали на фокспро, а потом пацаны сказали, что SQL server типа круто".
  • Игорь Шевченко © (29.08.08 13:32) [23]
    Где б программистов взять...
  • DiamondShark © (29.08.08 13:33) [24]

    > профессионалы стараются избегать триггеров

    Профессионалы в какой области? Профессионалы-гинекологи, возможно, и стараются избегать. Профессионалы-программисты СУБД триггеры знают, любят и умеют применять по назначению.
  • DiamondShark © (29.08.08 13:38) [25]

    > Транзакции в триггере есть безусловное зло :)

    Это смотря на каком сервере.
    На MSSQL, который, судя по синтаксису, у автора -- таки да.
    На других, у которых поведение транзакций не такое удодское, вполне себе имеет право на жизнь.
  • sql (29.08.08 13:58) [26]
    Сорри, а как производится пакетная вставка ?
  • DiamondShark © (29.08.08 14:16) [27]
    Сорри, а что такое "пакетная вставка"?

    Bulk insert, что-ли? Она производится быстро. Триггеры, кстати, при ней могут не срабатывать (зависит от опций).

    Или что-то другое имелось в виду?
  • sql (29.08.08 14:17) [28]

    > Или что-то другое имелось в виду?

    А я хз, потому и спрашиваю...
  • DiamondShark © (29.08.08 14:37) [29]

    > А я хз, потому и спрашиваю...

    Жжошь.
    Чего ты хз? Ты эти волшебные слова где услышал?
  • stas © (29.08.08 14:42) [30]
    sql   (29.08.08 13:58) [26]
    Insert Into
    select from

    При этом Select возвращает не 1 запись а много.
  • stas © (29.08.08 14:45) [31]
    Я так понимаю в переменные ты хочешь записывать значения из Inserted,Deleted или я неправильно понял?
  • sql (29.08.08 14:47) [32]

    > stas ©   (29.08.08 14:45) [31]

    Правильно.
  • Курдль (29.08.08 14:47) [33]

    > Polevi ©   (29.08.08 12:02) [4]
    > профессионалы стараются избегать триггеров


    Это сильно сказано! Также как и слова, что вся целостность данных может быть поддержана "... такими как PK-FK constraints... ХП"

    Да. Даже не знаю, что ответить...
    Особенно про ХП? Знаю такой стиль - применение ХП вместо DML.
    Мало того, что это геморрой, но еще и обрубает все пути автоматизации генерирования этих DML средами разработки.

    Вот пример для разминки ума.
    Есть рефлексивная связь в сущности Х. (Дерево - в простонародьи).
    Отследите-ка логическую ошибку "кольцевой связи" (т.е. если экземпляр сущности А является родительским для В. В - родительским для С. С - родительским для А).
  • sql (29.08.08 14:48) [34]

    > Чего ты хз?

    хто его знает...


    Ты эти волшебные слова где услышал?

    Кто его знает...
  • stas © (29.08.08 14:51) [35]
    DiamondShark ©   (29.08.08 14:37) [29]
    Это я писал выше.
    sql   (29.08.08 14:48) [34]
    он о пакетной вставке говорит :-D
  • stas © (29.08.08 14:53) [36]
    sql   (29.08.08 14:47) [32]
    Вот, а если пройдет одновременная вставка или апдейт 10 записей, Inserted будет содержать 10 записей, как ты их сохранишь в переменные?
  • Ega23 © (29.08.08 14:55) [37]

    > Особенно про ХП? Знаю такой стиль - применение ХП вместо
    > DML.
    > Мало того, что это геморрой, но еще и обрубает все пути
    > автоматизации генерирования этих DML средами разработки.


    понеслось...
    Однако - пятница...
  • sql (29.08.08 14:57) [38]

    > он о пакетной вставке говорит :-D

    Нет, это ты о покетной вставке говоришь. Я о ней просто спросил: "Что это ?". Потому что сразу не понял....

    ЗЫ:


    > stas ©   (29.08.08 12:30) [18]
    > Вверху общие.
    >
    > Я сразу скажу этот лог (как в примере) работать будет некорректно
    > при пакетной вставке, удалении обновлении.


    Ну поидеи Inserted, ...., ....d, по одной записи содержат..., или все же если пакетная вставка, ..., ..., весь пакет записей и держат... ?
  • sql (29.08.08 14:58) [39]

    > Вот, а если пройдет одновременная вставка или апдейт 10
    > записей, Inserted будет содержать 10 записей, как ты их
    > сохранишь в переменные?


    получил ответ на вопрос.

    Ну поидеи Inserted, ...., ....d, по одной записи содержат..., или все же если пакетная вставка, ..., ..., весь пакет записей и держат... ?

    ...
  • stas © (29.08.08 15:01) [40]
    sql   (29.08.08 14:57) [38]
    Весь, для этого  и таблица, а не переменные в самом триггере.
    Триггер выполнится столько раз сколько выполнишь запрос независимо сколько обновилось записей.
  • DiamondShark © (29.08.08 15:11) [41]

    > sql   (29.08.08 14:57) [38]
    >
    >
    > > он о пакетной вставке говорит :-D
    >
    > Нет, это ты о покетной вставке говоришь. Я о ней просто
    > спросил: "Что это ?". Потому что сразу не понял....


    А в русском написании это неоднозначный термин.
    Его можно понять и как bulk insert, и как insert ... select, и ещё хз как.
    Поэтому и спросили, что ты под этим понимаешь. А ты -- хз.


    > Ну поидеи Inserted, ...., ....d, по одной записи содержат.
    > .., или все же если пакетная вставка, ..., ..., весь пакет
    > записей и держат... ?

    Все записи, которые затрагивает выполняющийся оператор.
  • sql (29.08.08 15:21) [42]

    > DiamondShark ©   (29.08.08 15:11) [41]

    Хорошо, если я делаю пакетную вставку, тогда как мне отобразить записи в логе которые я вставил, т.е. лог не обычный клон той таблици в которой триггер, а в общей таблице для логирования событий, думаю примерно понятно о чем речь... Тогда прейдется в триггере делать cursor, чтоб он перелил каждую запись, или нет ?
  • MsGuns © (29.08.08 15:22) [43]
    >DiamondShark ©   (29.08.08 13:28) [22]
    >Нет такой "концепции".

    Есть только одна "концепция" - твоя. Остальное - бред сивой кобылы ;)
  • Курдль (29.08.08 15:27) [44]

    > В какой части текста триггера лучше всего открывать глобальную,
    >  по отношению к триггеру, транзакцию ?

    А я вот не поленился почитать Ваш код и ужаснулся - это я так отстал от жизни, или триггер ... BEFORE INSERT... существует только в оракле?
  • Игорь Шевченко © (29.08.08 15:36) [45]
    MsGuns ©   (29.08.08 15:22) [43]

    Не надо садиться в лужу лишний раз
  • Polevi © (29.08.08 15:44) [46]
    >DiamondShark ©   (29.08.08 13:33) [24]

    >Профессионалы-программисты СУБД триггеры знают, любят и умеют >применять по назначению.

    но при этом стараются избегать
  • stas © (29.08.08 15:46) [47]
    sql   (29.08.08 15:21) [42]

    пример №1
    ...
    Declare @username nvarchar(256), @time datetime
    set @username = SUSER_SNAME()
    set @time = GETDATE()

    Insert into logtable (ftime,fuser,f1,f2..fn)
    select @time,@username,f1,f2..fn from inserted

    Пример №2

    Insert into logtable (ftime,fuser,f1,f2..fn)
    select GETDATE(),SUSER_SNAME(),f1,f2..fn from inserted
  • Курдль (29.08.08 15:49) [48]

    > Курдль   (29.08.08 15:27) [44]
    > А я вот не поленился почитать Ваш код и ужаснулся - это
    > я так отстал от жизни, или триггер ... BEFORE INSERT...
    > существует только в оракле?


    Уф! Слава Богу - не только в оракле! Не поленился отрыть свои "труды" многолетней давности под Sybase ASA:


    create trigger XXX_TR_CNTR_BEFORE_I_U before insert, update on XXX_CONTRACTS
    referencing new as N old as O
    for each row
    begin
     declare cntrID Integer;
     if ((select CNTR_ID from XXX_CONTRACTS C1 where (C1.CNTR_TYPE = 1) and
                                                    (C1.SBJ_ID_INS = N.SBJ_ID_INS) and (C1.SBJ_ID_CUS = N.SBJ_ID_CUS) and
                                                    (C1.CNTR_ACTIV is Not null)) <> N.CNTR_ID) and (N.CNTR_TYPE = 1)
       then raiserror 23002 'XXX SERVER ERROR: В силе может быть только один договор xxx со xxx
     end if;
     
     if (N.CNTR_ID_PR is not null) then

       if N.CNTR_ID_PR = N.CNTR_ID
         then raiserror 23003 '
    XXX SERVER ERROR: Договор не может быть первичным для самого себя'
       end if;

       set cntrID = N.CNTR_ID_PR;
       while (cntrID <> 0) loop
         set cntrID = (select first(C2.CNTR_ID_PR) from XXX_CONTRACTS C2 where C2.CNTR_ID = cntrID);
         if (cntrID = N.CNTR_ID)
           then raiserror 23005 '
    XXX SERVER ERROR: Кольцевая связь первичных и подчиненных договоров'
         end if;
       end loop;

       if (select max(C2.CNTR_START_DATE) from XXX_CONTRACTS C2 where C2.CNTR_ID = N.CNTR_ID_PR) > N.CNTR_START_DATE
         then raiserror 23006 '
    XXX SERVER ERROR: Подчиненный договор не может быть подписан ранее первичного'
       end if;

     end if;

     if (select min(C2.CNTR_START_DATE) from XXX_CONTRACTS C2 where C2.CNTR_ID_PR = N.CNTR_ID) < N.CNTR_START_DATE
       then raiserror 23007 '
    XXX SERVER ERROR: В наличии подчиненные договоры, подписанные ранее настоящего'
     end if;

     if (N.CNTR_END_DATE is not Null) and (N.CNTR_END_DATE < N.CNTR_START_DATE)
       then raiserror 23009 '
    XXX SERVER ERROR: Дата подписания не может превышать дату окончания'
     end if;
    end;

  • stas © (29.08.08 15:49) [49]
    sql   (29.08.08 15:21) [42]
    неделай курсор в триггере!
  • stas © (29.08.08 15:51) [50]
    Курдль   (29.08.08 15:49) [48]
    в ms sql тоже есть.
  • Курдль (29.08.08 15:58) [51]

    > stas ©   (29.08.08 15:51) [50]
    >
    > Курдль   (29.08.08 15:49) [48]
    > в ms sql тоже есть.

    А чего тогда аутор копья ломает о мельницы?
  • stas © (29.08.08 16:04) [52]
    Курдль   (29.08.08 15:58) [51]
    несилен в sql видимо. Да там и ненужны транзакции.
  • DiamondShark © (29.08.08 16:20) [53]

    > sql   (29.08.08 15:21) [42]
    > > DiamondShark ©   (29.08.08 15:11) [41] Хорошо, если я
    > делаю пакетную вставку, тогда как мне отобразить записи
    > в логе которые я вставил, т.е. лог не обычный клон той таблици
    > в которой триггер, а в общей таблице для логирования событий,
    >  думаю примерно понятно о чем речь... Тогда прейдется в
    > триггере делать cursor, чтоб он перелил каждую запись, или
    > нет ?

    Можно курсор, можно insert into logtable(...) select ... from inserted

    Зависит от сложности преобразований над вставленными строками.
  • DiamondShark © (29.08.08 16:27) [54]

    > Курдль   (29.08.08 15:49) [48]
    > Слава Богу - не только в оракле! Не поленился отрыть свои "труды"
    > многолетней давности под Sybase ASA:


    О, да. У Sybase ASA очень хороший диалект SQL.
    Как вам квалификаторы for each row/for each statement для триггеров?

    А у MSSQL таки нет BEFORE триггеров.
    Зато есть INSTEAD триггеры.
  • DiamondShark © (29.08.08 16:34) [55]

    > MsGuns ©   (29.08.08 15:22) [43]
    >
    > >DiamondShark ©   (29.08.08 13:28) [22]
    > >Нет такой "концепции".
    >
    > Есть только одна "концепция" - твоя. Остальное - бред сивой
    > кобылы ;)

    Не совсем так, но тренд ты уловил.


    > Polevi ©   (29.08.08 15:44) [46]
    >
    > >DiamondShark ©   (29.08.08 13:33) [24]
    >
    > >Профессионалы-программисты СУБД триггеры знают, любят и
    > умеют >применять по назначению.
    >
    > но при этом стараются избегать

    Врядли Вы знакомы со ВСЕМИ специалистами или обладаете единственно верным представлением о специалистах. Поэтому обобщённое заявление такого рода, мягко говоря, не корректно.

    Вот заявления, вроде: "Я стараюсь избегать" или: "Известные мне специалисты стараются избегать" возражений не вызывают. Правда, и ценности не имеют.
  • stas © (29.08.08 16:35) [56]
    DiamondShark ©   (29.08.08 16:27) [54]
    Ну, да - INSTEAD. Они могут заменить BEFORE.
  • MsGuns © (29.08.08 16:55) [57]
    >Игорь Шевченко ©   (29.08.08 15:36) [45]
    >Не надо садиться в лужу лишний раз

    О "луже" поподробнее, пожалуйста
  • DiamondShark © (29.08.08 17:27) [58]
    Лужа -- относительно мелкое углубление в плотном верхнем слое грунта или искусственном покрытии, заполненное жидкостью, преимущественно, дождевой либо талой водой, часто с заметным количеством взвешенных частиц грунта и других веществ, присутствующих в атмосфере и на подлежащей поверхности.
    Посадка в лужу состоит в погружении ягодиц в наполняющую лужу жидкость на всю глубину лужи. Вхождение ягодиц в лужу сопровождается характерным звуком и, при значительной вертикальной составляющей скорости вхождения ягодиц в лужу, разбрызгиванием содержимого лужи и, в случае грунтового основания, размокшего грунта.
  • XentaAbsenta © (29.08.08 20:08) [59]
    Категорично против триггеров,
    категорично против транзакций в триггерах!

    ТРИГГЕРЫ ЗЛО
    ТРИГГЕРЫ ЗЛО
    ТРИГГЕРЫ ЗЛО
    ТРИГГЕРЫ ЗЛО
    ТРИГГЕРЫ ЗЛО

    Если кому будет интересно - обосную
  • Petr V. Abramov © (30.08.08 16:38) [60]

    > DiamondShark ©   (29.08.08 13:28) [22]

    +1
  • Petr V. Abramov © (30.08.08 17:45) [61]

    > Особенно про ХП? Знаю такой стиль - применение ХП вместо
    > DML.
    что геморройного?

    > Мало того, что это геморрой, но еще и обрубает все пути
    > автоматизации генерирования этих DML средами разработки.
    >

    а что, средства разработки уже умеют делать что-то сложнее, чем нагенерить insert-update-delete одной таблицы, да и то при insert не зная откуда ключ взять?
  • MsGuns © (31.08.08 00:40) [62]
    >DiamondShark ©   (29.08.08 17:27) [58]

    Какое доскональное знание предмета ! Сразу чувствуется гигантский практический опыт.
  • Petr V. Abramov © (31.08.08 00:54) [63]

    > Отследите-ка логическую ошибку "кольцевой связи" (т.е. если
    > экземпляр сущности А является родительским для В. В - родительским
    > для С. С - родительским для А).

    "тоже мне бином Ньютона"
    update потом select ... start with PARENT_ID = :1
    если ошибка, то цикл
  • stas © (31.08.08 12:58) [64]
    XentaAbsenta ©   (29.08.08 20:08) [59]
    интересно.
  • Курдль (01.09.08 14:06) [65]

    > Petr V. Abramov ©   (31.08.08 00:54) [63]
    > "тоже мне бином Ньютона"
    > update потом select ... start with PARENT_ID = :1
    > если ошибка, то цикл


    1. Сколько СУБД понимают "
    select ... start with PARENT_ID = :1

    "?
    2. Нужен ли клиенту СУБД весь этот сыр-бор с селектами/апдэйтами?
    3. Есть ли вероятность того, что между апдэйтом, селектом и реакцией на ошибку, кто-то из клиентов поимеет и употребит во зло измененную запись вместе с ошибкой?
  • Cobalt (01.09.08 14:12) [66]
    > Petr V. Abramov ©   (31.08.08 00:54) [63]

    И...? в случае ошибки программа зависнет в цикле? Так будете отлавливать?
  • Игорь Шевченко © (01.09.08 14:13) [67]
    XentaAbsenta ©   (29.08.08 20:08) [59]


    > ТРИГГЕРЫ ЗЛО
    > ТРИГГЕРЫ ЗЛО
    > ТРИГГЕРЫ ЗЛО
    > ТРИГГЕРЫ ЗЛО
    > ТРИГГЕРЫ ЗЛО
    >
    > Если кому будет интересно - обосную


    Ламерам удавиться и сдохнуть
  • MsGuns © (01.09.08 14:42) [68]
    >Игорь Шевченко ©   (01.09.08 14:13) [67]
    >> ТРИГГЕРЫ ЗЛО

    В некоторых случаях 100%

    >Ламерам удавиться и сдохнуть

    Как и некоторым здешним "академикам" ;)
  • evvcom © (01.09.08 15:04) [69]

    > Cobalt   (01.09.08 14:12) [66]
    >
    > > Petr V. Abramov ©   (31.08.08 00:54) [63]
    >
    > И...? в случае ошибки программа зависнет в цикле? Так будете
    > отлавливать?

    Ты не понял. Если сервер сообщит об ошибке, то допущен цикл в связке.
    А вообще каждый инструмент хорош при его правильном использовании. Триггер нужен на своем месте, хп на своем.
  • Petr V. Abramov © (01.09.08 16:18) [70]

    > Курдль   (01.09.08 14:06) [65]


    > 1. Сколько СУБД понимают "select ... start with PARENT_ID
    > = :1"?

    одна :)

    > 2. Нужен ли клиенту СУБД весь этот сыр-бор с селектами/апдэйтами?

    КЛИЕНТУ - не нужен, для того хранимки и придумали

    > 3. Есть ли вероятность того, что между апдэйтом, селектом
    > и реакцией на ошибку, кто-то из клиентов поимеет и употребит
    > во зло измененную запись вместе с ошибкой?

    если после update не всобачен commit - то нету
    > Cobalt   (01.09.08 14:12) [66]
    > > Petr V. Abramov ©   (31.08.08 00:54) [63]
    >
    > И...? в случае ошибки программа зависнет в цикле? Так будете
    > отлавливать?

    нет, select вызовет ошибку, код не помню
  • Курдль (01.09.08 16:36) [71]

    > Petr V. Abramov ©   (01.09.08 16:18) [70]
    > нет, select вызовет ошибку, код не помню


    А не вернет ли пустой набор?
    Если ты имеешь в виду ораклевый
    connect by prior start with

    ...
  • evvcom © (01.09.08 17:02) [72]

    > А не вернет ли пустой набор?
    > Если ты имеешь в виду ораклевый connect by prior start with...

    Нет, вызовет исключение.
  • Petr V. Abramov © (01.09.08 17:07) [73]

    > Курдль   (01.09.08 16:36) [71]

    нет, именно ошибку
    ORA-01436: CONNECT BY loop in user data
  • Petr V. Abramov © (01.09.08 23:52) [74]
    поп факту ж.. в данных можно найти с помощью
    CONNECT_BY_ISCYCLE pseudocolumn
    и
    CONNECT BY NOCYCLE PRIOR
    но:
    в 10.2.ххх работает стабильно, в 8.1.7.4 нету.
  • Кщд (02.09.08 07:58) [75]
    >XentaAbsenta ©   (29.08.08 20:08) [59]
    >Категорично против триггеров,
    >категорично против транзакций в триггерах!
    с удовольствием послушаю о причинах
    да, и где записывают в вашу секту?
  • Курдль (02.09.08 13:05) [76]

    > Petr V. Abramov ©   (01.09.08 16:18) [70]
    > КЛИЕНТУ - не нужен, для того хранимки и придумали


    Для чего? У меня есть фигова туча наработок под клиенты и апп.серверы  - целые классы, даже скажу пафоснее - паттерны! Они расшифровывают мои замысловатые многотабличные датасэты, чтобы сгенерировать DML. Они подстраиваются под конкретную СУБД и конкретный драйвер соединения. Они исправно работают от проекта к проекту и еще и совершенствуются в своем универсализме. А ты хочешь, чтобы я взял каменный топор и пошел писать "хранимки" под каждый датасэт?
    Вот без триггеров представить себе работу не могу... Рад бы от них отказаться - но не получается.
  • Petr V. Abramov © (02.09.08 13:44) [77]

    > даже скажу пафоснее - паттерны!
    ... чтобы сгенерировать DML

    позволю себе опошлить: == "шаблоны хранимок" в профиль
    :)))

    > А ты хочешь, чтобы я взял каменный топор и пошел писать "хранимки" под каждый датасэт?
    а если что-то в шаблон не укладывается, то на pl/sql писать проще, чем извращаться на студии или дельфях.

    Конечно, если надо делать что-то СУБД-независимое, твой подход получается верным.
    Но если не надо, то проще пользоваться мощнейшим pl/sql`ем, чем C# или VB, которые для работы с реляционными данными просто не заточены
  • Курдль (02.09.08 14:08) [78]

    > Petr V. Abramov ©   (02.09.08 13:44) [77]
    >  чем C# или VB, которые для работы с реляционными данными
    > просто не заточены


    ADO.NET для работы с реляционными данными заточены!
    На то есть датасэты с реляциями.
  • Petr V. Abramov © (02.09.08 14:39) [79]

    > На то есть датасэты с реляциями.

    а что делать-то с этими реляциями?
    foreign-ключи на клиенте проверять?

    растолкуй смысл, я его действительно не понимаю
  • Курдль (02.09.08 15:52) [80]

    > Petr V. Abramov ©   (02.09.08 14:39) [79]
    > а что делать-то с этими реляциями?
    > foreign-ключи на клиенте проверять?
    >
    > растолкуй смысл, я его действительно не понимаю


    Один смысл ты и сам написал: foreign-ключи на клиенте проверять
    2. Весело и задорно пользовать возможности
    public DataRow[] GetChildRows (DataRelation relation)


    3. Весело и задорно пользовать возможности
    DataRow.GetParentRows (DataRelation)


    4. Использовать объект, максимально точно инкапсулирующий какую-либо структуру данных из предметной области.
    5. Создавать и использовать классы, способные автоматически обрабатывать сложные структуры данных.
  • Petr V. Abramov © (02.09.08 16:39) [81]

    > Один смысл ты и сам написал: foreign-ключи на клиенте проверять

    это хорошо для одпользовательской системы иначе пустая трата времени


    > 2. Весело и задорно пользовать возможности
    > public DataRow[] GetChildRows (DataRelation relation)

    бегать по ним, обрабатывать...

    update ...
    set ... = (select ...
    where not exists (....
    returning ...

    всяко меньше букаф и лучше по скорости

    опять же, если база - foxpro, то 2-5 - вкусно, если oracle -совсем нет
  • evvcom © (02.09.08 16:48) [82]
    Подобные вкусности (универсальность) с точки зрения "написал программу, и она под любой осью работает", тоже уже реализовали в java. Но как я только сталкиваюсь с жутко тормозящим приложением, первая мысль - это java. Взять тот же инсталлятор оракловый. Насколько хороша СУБД, настолько же плох ее инсталлятор. Нельзя написать универсальное приложение, чтобы оно всех и во всем устраивало.
  • evvcom © (02.09.08 16:52) [83]

    > бегать по ним, обрабатывать...
    >
    > update ...
    > set ... = (select ...
    > where not exists (....
    > returning ...
    >
    > всяко меньше букаф и лучше по скорости

    уууу.... А если еще аналитические функции оракловые вспомнить, то ADO.NET вообще глаза выпучит! А они, ой, как иной раз скорости добавляют :-)
  • Petr V. Abramov © (02.09.08 16:55) [84]

    > evvcom ©   (02.09.08 16:52) [83]

    ага
  • Petr V. Abramov © (02.09.08 16:56) [85]
    кстати о птичках: а не пора ли в потрепаловку?
    :)
 
Конференция "Базы" » Транзакции в триггере
Есть новые Нет новых   [134473   +28][b:0.001][p:0.003]