Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Сравнение СУБД Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 .. 8 9 10 11 12 13 [14] 15 16 17   вперед  Ctrl
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
Теперь позвольте мне поставить проблему.
Запрос
select sum(store_sales) Sum from sales_fact_1997 t
where customer_id = 2094
and product_id=173;

возвращает неправильный результат.

Неправильность состоит в том, что в технологическое время сервер устойчиво возвращает результат 785.28, а при многопользовательской работе сумма чуть другая. К серверу поступают операторы изменения только вот такого типа:
begin transaction
update sales_fact_1997 set 
STORE_COST=1.95,
STORE_SALES=4.68
where ID = 1;
update sales_fact_1997 set 
STORE_COST=1.84,
STORE_SALES=4.29
where ID = 28794421;
commit;

то есть, только операторы НЕ меняющие баланс по клиенту+товару! Стоит остановить поток изменений - и баланс "возвращается" на место.

В чем может быть причина?
29 окт 04, 14:31    [1071519]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
И еще такая "простенькая" задачка:

Есть стороннее приложение, поддерживаемое разработчиком (т.е., любое изменение - потеря поддержки). В приложении есть разделение прав по отделам - каждый отдел видит только свои проводки. Но Вам неожиданно поставили задачу - ввести разграничение доступа к проводкам по их суммам! Т.е., большие сделки (больше XXXX) могут видеть только "особо уполномоченные".

Как бы Вы поступили в этом случае?
29 окт 04, 14:36    [1071542]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 67534
Блог
Pi
И еще такая "простенькая" задачка:

Смотря что Вы называете "изменением". При некотором понимании задача неадминистративного решения не имеет :)

Подразумевающийся ответ для Oracle - FGAC, он же row level security, он же DBMS_RLS.

Универсальное, не зависящее от сервера решение - сбрасывать дешевые проводки в отдельную базу.

Хм. Ну еще можно клиента подпатчить - так, чтобы ненужные строки пропускались в датасетах, возвращаемых в клиентское приложение.
29 окт 04, 14:43    [1071574]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
vadiminfo
SergSuper

Может еще кто напишет примеры для других СУБД

Оракл не рекомендует рекурсий в триггерах, т.е. на DML delete, чтобы и в триггере DML delete для той же таблы по причине резкого расхода памяти.

Конечно, можно, например, такое написать:

create or replace trigger ttt
AFTER DELETE
ON tree
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
DELETE FROM tree WHERE parent = :OLD.id;
COMMIT;
END;

Но недостатком будет, наприер, то, что в случае отката операции:
delete from tree where id = 1
все потомки id = 1 будут удалены, а сам этот узел останется. Это не подойдет для ограничений целостности.

vadiminfo,
Ваш код работает, и работает достаточно быстро - 2, 403 сек. Его "недостаток" - отсутствие возможности отката, - не очень существеннен в обсуждаемом примере, поскольку триггер-то стоит AFTER, когда уже все проверили, а возможность срабатывания триггеров на других таблицах в нашем примере не обсуждается - ведь это не из реальной жизни. В реальной жизни обсуждаемый пример решается совсем по другому
29 окт 04, 14:49    [1071611]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
protector
Member

Откуда: Иваново, Россия
Сообщений: 600

Pi
Его "недостаток" - отсутствие возможности отката, - не очень существеннен в обсуждаемом примере, поскольку триггер-то стоит AFTER, когда уже все проверили, а возможность срабатывания триггеров на других таблицах в нашем примере не обсуждается - ведь это не из реальной жизни. В реальной жизни обсуждаемый пример решается совсем по другому

Не могли бы Вы пояснить, что значит не очень существеннен? В этом примере- возможно, а в некоторых задачах очень существенен. Кстати, как Вы себе представляете этот тригер [sql]BEFORE FOR EACH ROW[/sql]? А решение, т.к. настоящее "из реальной жизни" попахивает извращением. Почему я должен делать два тригера вместо одного да ещё и пихать данные в таблицу, а потом оттуда вытаскивать? Почему великий и могучий Оракул до сих пор не имеет в общем-то простой и нужной возможности?


Posted via ActualForum NNTP Server 1.1

29 окт 04, 15:22    [1071751]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
protector

Почему я должен делать два тригера вместо одного да ещё и пихать данные в таблицу, а потом оттуда вытаскивать? Почему великий и могучий Оракул до сих пор не имеет в общем-то простой и нужной возможности?


Posted via ActualForum NNTP Server 1.1


Каков вопрос - таков ответ. Была поставлена задача г. SergSuper (а где он, кстати?) в его посте от 27 окт 04, 15:40 (см. эту ветку, стр. 12).

НЕ выходя за пределы задачи, было предложены решения. Например, оказалось, что приведенный самим SergSuper код валится на 32 циклах вложенности. Подобный (подчеркну - подобный) код на Oracle валится на 50 вложениях.

Но есть обходные примеры, которые показали пока только на ASA и Oracle. Ждем подобных примеров на MS SQL! Желательно с проверкой на большом количестве данных - я указал возможную таблицу для тестирования.

А на самом деле предложенная г. SergSuper задача по-сути решается совсем по-другому - через FK on DELETE CASCADE.
29 окт 04, 15:34    [1071797]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
softwarer
Pi
И еще такая "простенькая" задачка:

Смотря что Вы называете "изменением". При некотором понимании задача неадминистративного решения не имеет :)

Подразумевающийся ответ для Oracle - FGAC, он же row level security, он же DBMS_RLS.

Универсальное, не зависящее от сервера решение - сбрасывать дешевые проводки в отдельную базу.

Хм. Ну еще можно клиента подпатчить - так, чтобы ненужные строки пропускались в датасетах, возвращаемых в клиентское приложение.


Пан softwarer,
я совершенно согласен с Вами в предложенном решении для Oracle.

А кто что предложит для других баз?

Теперь позвольте свой комментарий.
Oracle сегодня (впрочем, и вчера тоже!), в коммерческом релизе, дает возможность значительно увеличить детальность доступа к данным без изменения приложений (и без потери поддержки!). Фактически, имея на руках коммерческий Oracle, можно создавать приватные базы.
29 окт 04, 15:40    [1071820]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
ASCRUS
Ну раз пошла такая пьянка, приведу и я для ASA триггер
...
Что мы с него видим:
1. Он сделан как FOR EACH STATEMENT и будет вызываться только один раз для всего множества удаляемых нодов с дерева.
2. В ASA поддерживаются глобальные сессионные переменные
3. В ASA нет опций запрета вызова рекурсий, все это можно разрулить через глобальные переменные
4. В ASA есть времянки, которые не участвуют в транзакциях, что соотвествующе прибавляем им скорости работы.
5. В ASA есть рекурсивные запросы, которые можно применять в SELECT и INSERT, но не в DELETE. Соотвествующе поэтому и была создана времянка.
6. В ASA есть понятие исключений для блоков BEGIN..END и соотвествующая обработка их.


ASCRUS,
а как Вы в Dfitv коде получили доступ к удаленным записям? В MS SQL - это записи в deleted, а в ASA?

thanks in advance!
29 окт 04, 15:59    [1071882]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
ASCRUS
Ну раз пошла такая пьянка...
В дополнение - мне лично WITH RECURSIVE, использующийся для обработки деревьев в ASA и DB2 нравиться больше, чем Ораклевый вариант. Вместо обьяснений приведу пример почему:
WITH RECURSIVE h (Parent_id, Node_id, Level, Path) AS (
  SELECT Parent_id, ProductGroup_id, 0, ProductGroup_id
  FROM ProductGroup
  WHERE Parent_id IS NULL
  UNION ALL
  SELECT g.Parent_id, g.ProductGroup_id, h.Level + 1, h.Path || '/' || g.ProductGroup_id
  FROM ProductGroup g
    INNER JOIN h ON h.Node_id = g.Parent_id )
SELECT Replicate('-', Level * 4) || Name AS Name, h.*
FROM h
  INNER JOIN ProductGroup pg ON pg.ProductGroup_id = h.Node_id
ORDER BY Path;
А это результат:
NameParent_idNode_idLevelPath
'Продукты питания''Прод'0'Прод'
'----Молочные продукты''Прод''Молоч'1'Прод/Молоч'
'----Хлебобулочные изделия''Прод''Хлеб'1'Прод/Хлеб'
'Техника''Тех'0'Тех'
'----Бытовая техника''Тех''БытТех'1'Тех/БытТех'
'----Видеоэлектронника''Тех''ВидеоТех'1'Тех/ВидеоТех'
'--------Видеомагнитофоны''ВидеоТех''ВМ'2'Тех/ВидеоТех/ВМ'
'--------Телевизоры''ВидеоТех''ТВ'2'Тех/ВидеоТех/ТВ'

Из за того, что в рекурсивном запросе можно отдельно указать запрос, откуда брать родителей и запрос, откуда брать детей, можно:
1. Строить рекурсивные запросы по деревьям, хранящимся во множестве таблиц
2. Организовывать нарастающие переменные, в данном случае были организованы переменные Level (уровень вложености нода), которая использовалась для отступа в наименовании группы и Path (путь к ноду), по которой была произведена сортировка нодов относительно каждого родительского нода.
Насколько я понимаю, чтобы все это проделать в Оракле одним чистым запросом отделаться нельзя будет.

P.S. Красивее было бы конечно в наименовании отступы ставить пробелами, но у Judge тэг CSV их кушает дюже хорошо :)

select LPAD(' ',2*(LEVEL-1)) || ename ename, 
    empno, mgr, job,  sys_connect_by_path( ename, '/' ) path   from emp
    start with ename='KING'
    connect by prior empno = mgr;
SQL> 

ENAME                                                                            EMPNO   MGR JOB       PATH
-------------------------------------------------------------------------------- ----- ----- --------- --------------------------------------------------------------------------------
KING                                                                              7839       PRESIDENT /KING
  JONES                                                                           7566  7839 MANAGER   /KING/JONES
    SCOTT                                                                         7788  7566 ANALYST   /KING/JONES/SCOTT
      ADAMS                                                                       7876  7788 CLERK     /KING/JONES/SCOTT/ADAMS
    FORD                                                                          7902  7566 ANALYST   /KING/JONES/FORD
      SMITH                                                                       7369  7902 CLERK     /KING/JONES/FORD/SMITH
  BLAKE                                                                           7698  7839 MANAGER   /KING/BLAKE
    ALLEN                                                                         7499  7698 SALESMAN  /KING/BLAKE/ALLEN
    WARD                                                                          7521  7698 SALESMAN  /KING/BLAKE/WARD
    MARTIN                                                                        7654  7698 SALESMAN  /KING/BLAKE/MARTIN
    TURNER                                                                        7844  7698 SALESMAN  /KING/BLAKE/TURNER
    JAMES                                                                         7900  7698 CLERK     /KING/BLAKE/JAMES
  CLARK                                                                           7782  7839 MANAGER   /KING/CLARK
    MILLER                                                                        7934  7782 CLERK     /KING/CLARK/MILLER

14 rows selected

Ответ корректен?
29 окт 04, 16:29    [1071981]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
PL99
Member

Откуда: Moscow
Сообщений: 1367
Pi
а как Вы в Dfitv коде получили доступ к удаленным записям? В MS SQL - это записи в deleted, а в ASA?

REFERENCING OLD AS ParentsDeleted
29 окт 04, 17:03    [1072091]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
ASCRUS
Member

Откуда: МО Электросталь
Сообщений: 5994
Pi
ASCRUS,
а как Вы в Dfitv коде получили доступ к удаленным записям? В MS SQL - это записи в deleted, а в ASA?

В ASA нет особых ограничений, как будут называться NEW и OLD внутри триггера, через опцию триггера REFERENCING им можно назначить любое удобное имя. С учетом того, что такие таблицы будут видны как временные из вызываемых с триггера процедур, то это удобно, если например у меня есть отдельно триггера на INSERT, UPDATE и DELETE и все они вызывают одну ХП, которой нужно по изменяемым записям что то сделать. В итоге достаточно во всех 3 триггерах назвать набор изменяемых данных одним именем и смело вызывать в каждом эту ХП.

Pi
Ответ корректен?

Если функция "sys_connect_by_path" является системной, то есть встроенна в Оракл, а не написана ручками Вами, то ответ корректен. Кстати я не вижу в запросе ORDER BY - в Оракл разрешается на рекурсивные запросы вешать сортировку и можно ли такие запросы использовать в качестве подзапросов ?
29 окт 04, 17:18    [1072142]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
PL99
Member

Откуда: Moscow
Сообщений: 1367
Есть в ASA еще одна удобная фича, о которой, по-моему, почему-то до сих пор не упомянули - можно создать несколько триггеров каждого вида (before row level, before statement level...) и явно указать порядок их срабатывания. В Oracle, например, этого нет.
Про MS SQL я и не говорю :-)
29 окт 04, 17:32    [1072185]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
ASCRUS
Если функция "sys_connect_by_path" является системной, то есть встроенна в Оракл, а не написана ручками Вами, то ответ корректен. Кстати я не вижу в запросе ORDER BY - в Оракл разрешается на рекурсивные запросы вешать сортировку и можно ли такие запросы использовать в качестве подзапросов ?

select LPAD(' ',2*(LEVEL-1)) || ename ename, 
    empno, mgr, job,  sys_connect_by_path( ename, '/' ) path   
    from emp
    start with ename='KING'
    connect by prior empno = mgr
    order by path;
QL> 

ENAME                                                                            EMPNO   MGR JOB       PATH
-------------------------------------------------------------------------------- ----- ----- --------- --------------------------------------------------------------------------------
KING                                                                              7839       PRESIDENT /KING
  BLAKE                                                                           7698  7839 MANAGER   /KING/BLAKE
    ALLEN                                                                         7499  7698 SALESMAN  /KING/BLAKE/ALLEN
    JAMES                                                                         7900  7698 CLERK     /KING/BLAKE/JAMES
    MARTIN                                                                        7654  7698 SALESMAN  /KING/BLAKE/MARTIN
    TURNER                                                                        7844  7698 SALESMAN  /KING/BLAKE/TURNER
    WARD                                                                          7521  7698 SALESMAN  /KING/BLAKE/WARD
  CLARK                                                                           7782  7839 MANAGER   /KING/CLARK
    MILLER                                                                        7934  7782 CLERK     /KING/CLARK/MILLER
  JONES                                                                           7566  7839 MANAGER   /KING/JONES
    FORD                                                                          7902  7566 ANALYST   /KING/JONES/FORD
      SMITH                                                                       7369  7902 CLERK     /KING/JONES/FORD/SMITH
    SCOTT                                                                         7788  7566 ANALYST   /KING/JONES/SCOTT
      ADAMS                                                                       7876  7788 CLERK     /KING/JONES/SCOTT/ADAMS

14 rows selected
Oracle9i SQL Reference
SYS_CONNECT_BY_PATH
Syntax
sys_connect_by_path::=


Text description of sys_connect_by_path


Purpose
SYS_CONNECT_BY_PATH is valid only in hierarchical queries. It returns the path of a column value from root to node, with column values separated by char for each row returned by CONNECT BY condition.

Both column and char can be any of the datatypes CHAR, VARCHAR2, NCHAR, or NVARCHAR2. The string returned is of VARCHAR2 datatype and is in the same character set as column.

See Also:
"Hierarchical Queries" for more information about hierarchical queries and CONNECT BY conditions

29 окт 04, 17:39    [1072207]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
protector
Member

Откуда: Иваново, Россия
Сообщений: 600

Pi
НЕ выходя за пределы задачи, было предложены решения. Например, оказалось, что приведенный самим SergSuper код валится на 32 циклах вложенности. Подобный (подчеркну - подобный) код на Oracle валится на 50 вложениях.

Но есть обходные примеры, которые показали пока только на ASA и Oracle. Ждем подобных примеров на MS SQL! Желательно с проверкой на большом количестве данных - я указал возможную таблицу для тестирования.

А на самом деле предложенная г. SergSuper задача по-сути решается совсем по-другому - через FK on DELETE CASCADE.

Да эта задача решается через FK. Просто вопрос от задачи перешёл к сравнению возможностей тригеров. Вот и я в ту же степь... Задача проверки констрейнтов, не реализуемых стандартными методами, обычно и возлагается на тригеры. А эти констрейнты могут быть очень сложные и что в таком случае делать? Селект-то из таблицы не сделаешь в for each row. Вот и приходится всё делать через одно место. ;)

Posted via ActualForum NNTP Server 1.1

29 окт 04, 17:49    [1072241]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
locky
Member

Откуда: Харьков, Украина
Сообщений: 62034


Есть в ASA еще одна удобная фича, о которой, по-моему, почему-то до сих пор не упомянули - можно создать несколько триггеров каждого вида (before row level, before statement level...) и явно указать порядок их срабатывания. В Oracle, например, этого нет.
Про MS SQL я и не говорю :-)

неправда ваша, дяденька! см. BOL sp_settriggerorder. Вот в чем горькая правда, так то, что триггер может быть только первым, последним или никаким :-).


Posted via ActualForum NNTP Server 1.1

29 окт 04, 17:52    [1072257]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
PL99
Есть в ASA еще одна удобная фича, о которой, по-моему, почему-то до сих пор не упомянули - можно создать несколько триггеров каждого вида (before row level, before statement level...) и явно указать порядок их срабатывания. В Oracle, например, этого нет.
Про MS SQL я и не говорю :-)


PL99,
во-первых, я хотел бы Вас лично вместе с г. ASCRUS поблагодарить за разъяснение
REFERENCING OLD AS ParentsDeleted
Спасибо!

Во-вторых, Ваш цитируемый пост чуть размыт, что позволяет сказать и "Вы правы", и "Вы не правы"

Вы привели несколько триггеров разного времени исполнения, так их порядок предопределен и неизменяем. Если же говорить о нескольких триггерах одного типа - то таки да, и в 9-1 версии их порядок неопределен.

С другой стороны, зависимость правильности действия триггеров от порядка их исполнения для меня лично сомнительна! Я, кстати, напарывался на эти проблемы, когда сопровождал с пяток "почти" однотипных объектов. С тех поря я для себя решил, что если порядок важен - то значительно правильнее написать "коротко-транзакционные" процедуры, и вызывать их из одного триггера. И зная еще с 98 года что такое возможно в Interbase, никогда этого порядка не жаждал. Впрочем, может у Вас есть готовый пример?

А кстати - есть понятие "коротких" транзакций в ASA? "Короткие" - это те, при помощи которых
Oracle, с незапамятных времен
Application developers can improve the performance of short, nondistributed transactions by using the BEGIN_DISCRETE_TRANSACTION procedure
29 окт 04, 17:52    [1072258]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
locky


Есть в ASA еще одна удобная фича, о которой, по-моему, почему-то до сих пор не упомянули - можно создать несколько триггеров каждого вида (before row level, before statement level...) и явно указать порядок их срабатывания. В Oracle, например, этого нет.
Про MS SQL я и не говорю :-)

неправда ваша, дяденька! см. BOL sp_settriggerorder. Вот в чем горькая правда, так то, что триггер может быть только первым, последним или никаким :-).


Posted via ActualForum NNTP Server 1.1


Хорошо бы указывать, где это. Не все здесь знают MS SQL.
29 окт 04, 17:54    [1072266]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
SergSuper
Member

Откуда: SPb
Сообщений: 5488
Так, что-то товарищ Pi меня совсем как-то опустил.

Во-первых я хотел узнать каков принцип работы с записями в триггерах на разныз СУБД. И первые ответы ввергли меня в пессимизм. Почти как в анекдоте:
У чукчи спрашивают: какой народ самый глупый? А он отвечает: Зато у нас песни красивые!
Т.е. вместо того чтоб написать примеры триггеров народ пишет что у них зато есть рекурсивные запросы и автономные транзакции и как нехорошо использовать рекурсивные триггеры. Замечательно, но я то не об этом.
Потом товарищ Pi переписал к себе мой триггер, который я писал не особо задумываясь и естественно не проверяя, был вне себя от щастья нашедши синтаксическую ошибку, исправил, и был еще больше щаслив когда его(а якобы мой) триггер не работал как надо. Потом он решил триггер усовершенствовать, убрав условие выхода из рекурсии и стал меня укорять что я написал ерунду (Пример в MS SQL, ВООБЩЕ ГОВОРЯ, НЕ РАБОТОСПОСОБЕН. Этот тот самый геморрой, о котором я имел место говорить). Ну что ж мне не жалко, всегда готов сделать приятное человеку.

К щастью дискуссия не ушла во флейм и появились действительно рабочие примеры, за что всем не поленившимся написать большое спасибо. Кстати хотелось бы увидеть как это делается на DB2 и InterBase.
Так же выкладываю проверенный пример на MS SQL, если уж витает мысль оформить это типа ФАКа. Здесь уже не используются рекурсивные триггера, из-за чего надо писать не очень красивую конструкцию с циклом.
create table tr( id int identity, parent int null, caption varchar(99))

go

create trigger ttt on tr for delete as
begin
set nocount on
declare @t table(i int primary key, le int)
declare @le int
set @le=0
insert @t select t.id, 0 from deleted d, tr t where t.parent=d.id
while @@rowcount<>0
  begin
    set @le=@le+1
    insert @t select id, @le 
      from @t, tr 
      where i=parent and le=@le - 1
  end

delete tr
  from tr , @t
  where id=i
end

go
----------  Далее идёт заполнение тестовыми данными

insert tr select null, 'root'
declare @i int
set @i=1
while @i<=1155
begin
insert tr select rand()*@@identity+1, 'Hello, Word!'
set @i=@i+1
end
go

----------  Проверяем за какое же время оно удалиться

declare @d datetime
select @d=getdate()
delete tr where id=1
select datediff(ms, @d,getdate())

И теперь я подведу первичные итоги(надеюсь кто меня знает поймёт правильно):

1. Приведенный пример в Oracle выглядит сложнее. С этим я с товарищем Pi полностью согласен. Выражаясь его языком - выглядит как этот тот самый геморрой.

2. Пример в Oracle работает очень медленно. Я, чесно говоря, не знаю как товарищу Pi удалось так тормознуть неплохую железяку, но у меня удаление на гораздо более простом сервере занимает 0.173 с теми же 1155 записями. И это без индексов.

3. ВООБЩЕ ГОВОРЯ, не стоит судить о геморе в MS SQL и о работоспособности примеров имея весьма слабое о нём представление.

4. Попутно желающие могут увидеть, что иерархические формы запроса довольно просто заменяются циклом и не выглядят более наглядными(для меня и самого это было неожиданностью - я всё жду Юкона, где это есть)

Поэтому прошу господ, ратующих за меганвороченность, вспоминать время от времени старую русскую поговорку -
Простота - залог надёжности
29 окт 04, 17:56    [1072276]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
А вот еще такая проблема.
В коде Oracle я могу
alter trigger Trigger_tr disable;
и, соответсвенно,
alter trigger Trigger_tr enable;

Уогда пересел на MS SQL (6.5), то необходимость
drop trigger Trigger_tr
(невозможность его отключить) приводила к полному безобразию - мы в Штаты гнали процедуры, которые дропали триггера и снова их ставили! Ну, у них там в судах Вирджинии народ делом занят, по системам сам не ползает, а представьте себе, если бы такой код поставили где-то здесь? Обязательно нашелся бы умник, который че-нибудь поменял бы в триггере, а потом бы удивлялся, чего все не так работает...

А как с этим у соседей? ASA? DB/2?
29 окт 04, 17:58    [1072283]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
PL99
Member

Откуда: Moscow
Сообщений: 1367
Pi
Вы привели несколько триггеров разного времени исполнения, так их порядок предопределен и неизменяем. Если же говорить о нескольких триггерах одного типа - то таки да, и в 9-1 версии их порядок неопределен.
Уточняю. Для нескольких before insert row level (например) триггеров можно явным образом указать порядок срабатывания.

Pi
С другой стороны, зависимость правильности действия триггеров от порядка их исполнения для меня лично сомнительна! Я, кстати, напарывался на эти проблемы, когда сопровождал с пяток "почти" однотипных объектов. С тех поря я для себя решил, что если порядок важен - то значительно правильнее написать "коротко-транзакционные" процедуры, и вызывать их из одного триггера. И зная еще с 98 года что такое возможно в Interbase, никогда этого порядка не жаждал. Впрочем, может у Вас есть готовый пример?
Вы правы, но я исхожу из положения - лишней фичи не бывает... К сожалению, готового примера у меня нет, т.к. я уже 6 лет не работаю с ASA.
29 окт 04, 18:00    [1072290]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
ASCRUS
Member

Откуда: МО Электросталь
Сообщений: 5994
автор
А вот еще такая проблема.
В коде Oracle я могу
alter trigger Trigger_tr disable;
и, соответсвенно,
alter trigger Trigger_tr enable;

Уогда пересел на MS SQL (6.5), то необходимость
drop trigger Trigger_tr
(невозможность его отключить) приводила к полному безобразию - мы в Штаты гнали процедуры, которые дропали триггера и снова их ставили! Ну, у них там в судах Вирджинии народ делом занят, по системам сам не ползает, а представьте себе, если бы такой код поставили где-то здесь? Обязательно нашелся бы умник, который че-нибудь поменял бы в триггере, а потом бы удивлялся, чего все не так работает...

А как с этим у соседей? ASA? DB/2?

Слишком старую версию Вы MSSQL вспомнили, сейчас там есть отключение триггеров на таблицу командой ALTER TABLE.

В ASA штатными средствами можно отключить только все триггера - через специальный параметр при запуске сервера (для всех сессий) или же установкой нужной темпоральной опции в сессии (только для этой сессии). Если хочется отключать отдельные группы триггеров, то все опять же разруливается через глобальные переменные, фактически мой пример на удаление по дереву триггера написанный выше как раз и демонстирует как отключить повторный рекурсивный вызов триггера. Кстати в ASA на соединение сессии можно указать автоматически запускать собственную ХП, в которой сразу же создавать и инициализировать нужные глобальные переменные, заполнять глобальные временные таблицы или даже проверить по какому то условию и дать от ворот поворот подключающейся сессии (например логин уже работает в БД или же кол-во одновременно подключаемых станций не может быть больше 10). Там же можно сразу по ходу подключения создавать/не создавать нужные глобальные переменные, если по логике необходимо включать или отключать группы триггеров. Вообще я считаю LOGIN процедуру чрезвычайно полезной фичой, позволяющей мне сразу же при начале коннекта сессии ее проинициализировать и подготовить к работе, что позволяет мне не только с клиентского приложения, но и с стандартных утилит ASA сразу под рукой иметь всю необходимую инициализацию без ручных вызов ХП (что не очень то сделаешь из под визуальных утилит ASA).
29 окт 04, 18:25    [1072347]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
SergSuper
Так, что-то товарищ Pi меня совсем как-то опустил.
...
Поэтому прошу господ, ратующих за меганвороченность, вспоминать время от времени старую русскую поговорку -
Простота - залог надёжности


SergSuper, Вы как-то болезненно все воспринимаете. Я никого не хочу опускать, я хочу чтобы именно здесь, на этой ветке, собралось побольше примеров - разных, хороших...и правильных!

Вот к примеру:
create table tr( id int identity, parent int null, caption varchar(99))

go

create trigger ttt on tr for delete as
begin
set nocount on
declare @t table(i int primary key, le int)
declare @le int
set @le=0
insert @t select t.id, 0 from deleted d, tr t where t.parent=d.id
while @@rowcount<>0
  begin
    set @le=@le+1
    insert @t select id, @le 
      from @t, tr 
      where i=parent and le=@le - 1
  end

delete tr
  from tr , @t
  where id=i
end

go
----------  Далее идёт заполнение тестовыми данными

insert tr select null, 'root'
declare @i int
set @i=1
while @i<=1155
begin
insert tr select rand()*@@identity+1, 'Hello, Word!'
set @i=@i+1
end
go

declare @d datetime
select @d=getdate()
delete tr where id=1
select datediff(ms, @d,getdate())
MS SQL
Server: Msg 217, Level 16, State 1, Procedure ttt, Line 17
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).


То есть, опять Ваш пример у меня не сработал! Честное слово, это Ваш пример, взятый с Вашего поста! Может, какие-то настройки сервера нужны?
Просьба указать их явно в коде.

ничто так не разнообразит жизнь как достойный противник
29 окт 04, 18:26    [1072349]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
ASCRUS
Member

Откуда: МО Электросталь
Сообщений: 5994
Попробуйте вот так:
create trigger ttt on tr for delete as
begin
set nocount on
declare @t table(i int primary key, le int)
declare @le int
set @le=0
insert @t select t.id, 0 from deleted d, tr t where t.parent=d.id
while @@rowcount<>0
  begin
    set @le=@le+1
    insert @t select id, @le 
      from @t, tr 
      where i=parent and le=@le - 1
  end

if exists( select * from @t )
  delete tr
    from tr , @t
    where id=i
end

P.S. Гм, я уже и писать чего то на TSQL разучился, хотел к IF прилепить THEN и END IF :)
29 окт 04, 18:32    [1072362]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
SergSuper
Member

Откуда: SPb
Сообщений: 5488
Да нет, скорее всего надо отключить рекурсивное выполнение триггеров
29 окт 04, 18:34    [1072365]     Ответить | Цитировать Сообщить модератору
 Re: А зачем нужен этот монстр....... MS SQL?  [new]
Pi
Member

Откуда:
Сообщений: 278
ASCRUS

Слишком старую версию Вы MSSQL вспомнили, сейчас там есть отключение триггеров на таблицу командой ALTER TABLE.
...
Там же можно сразу по ходу подключения создавать/не создавать нужные глобальные переменные, если по логике необходимо включать или отключать группы триггеров. Вообще я считаю LOGIN процедуру чрезвычайно полезной фичой, позволяющей мне сразу же при начале коннекта сессии ее проинициализировать и подготовить к работе, что позволяет мне не только с клиентского приложения, но и с стандартных утилит ASA сразу под рукой иметь всю необходимую инициализацию без ручных вызов ХП (что не очень то сделаешь из под визуальных утилит ASA).


1. Эт-то точно!
2.
Oracle9i Database Concepts
Application Context
Application context facilitates the implementation of fine-grained access control. It lets you implement security policies with functions and then associate those security policies with applications. Each application can have its own application-specific context. Users are not allowed to arbitrarily change their context (for example, through SQL*Plus).

Application contexts permit flexible, parameter-based access control, based on attributes of interest to an application. For example, context attributes for a human resources application could include "position," "organizational unit," and "country," whereas attributes for an order-entry control might be "customer number" and "sales region".

You can:

Base predicates on context values
Use context values within predicates, as bind variables
Set user attributes
Access user attributes

Может, это из этого ряда.
29 окт 04, 18:34    [1072366]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 .. 8 9 10 11 12 13 [14] 15 16 17   вперед  Ctrl
Все форумы / Сравнение СУБД Ответить