:: Visual Foxpro, Foxpro for DOS
Re: как программно сделать приватную датасесию
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
PaulWist
Как говорил т. Сталин: "Гинденбургов у меня для вас нет", те надо уметь работать с теми кто есть.
Большинство можно обучить и заставить работать правильно. Не занимаясь ЗА НИХ глупой работой.
PaulWist
Разница только в том, то в моём понимании состояние данных должно всегда соотвествовать БЛ, в твоём понимании состояние данных может находится в рассогласованном состоянии с БЛ, те (запись в Алкоголе может отсутствовать, тем не менее бука "А" в продукте может находиться).
Ещё раз по буквам. В моём понимании согласованность данных точно такая же как и в твоём.
Только обеспечивается она не "абы-когда" а лишь в согласованных снимках данных - грубо говоря на границе транзакций. И потому нарушение этой согласованности МЕЖДУ 2-мя insert-ами в рамках ОДНОЙ транзакции проблемой не является.
И да, контролировать всю БЛ может, естественно, лишь тот кто управляет транзакцией - да, это может быть ХП "для ввода алкоголя", и даже instead of триггер на специальную "алкогольную" вьюшку. Но никак не триггер на одну (или на обе) из "базовых" таблиц. Может это контролировать и сам клиент. Тем более что при использовании ORM это делает по сути системный код - прикладной разработчик НЕ ПИШЕТ эти insert-ы вручную!
PaulWist
Дык, в том-то и дело, что ты НИКОГДА не сможешь вытащить ветвь дерева если оно зациклено не на родительский узел, а на один из дочерних узлов одной ветви
1) Смотря как вынимать.
2) Если я хочу построить "дерево от элемента 1 вверх", то мне и НЕ НУЖНЫ ни "левые циклы", ни деревья от других корней - и это нормальное поведение, никаких ошибок в нём я не вижу. Конечно же запрос должен сам по себе не зацикливаться, если вдруг этот элемент 1 находится в цикле...
3) Не в курсе как ПРАВИЛЬНО писать подобный запрос для MSSQL. И даже допускаю что это невозможно в принципе. Что может говорить лишь о некотором недостатке данной СУБД при работе с "иерархическими данными", а никак не о том что нужно чего-то там городить для осуществления ненужных по своей сути проверок.
4) Ещё и ещё раз повторяю - НЕВОЗМОЖНО посредством триггеров осуществить ВСЕ виды "проверок целостности согласно бизнес-логике". О чём чуть ниже.
PaulWist
3. Ну вот, ты сам приводишь пример, (шапка и строки) рассогласованности данных с БЛ, с твоей точки зрения это норма для меня нет.
Ё-маё. Да как же НЕТ, когда ДА - когда ты сам страницу назад писал что у тебя строки "согласуются" (как глагол) с шапкой лишь при "утверждении/проведении" документа! Если ДО того как раз "поле в шапке" ни разу не соответствует "полям в строках"! И это "соответствие" НЕВОЗМОЖНО реализовать посредством триггеров. Никак! В принципе невозможно!
PaulWist
И это правильно, ты должен предусмотреть все возможные ситуации, а как ты это сделаешь - дело десятое.
Зачем? Это в технологическом софте цена ошибки велика, а в рядовом бухгалтерско-учётном - мизерна. И удорожать софт в 3-4 раза совершенно нецелесообразно. При том что гарантировать на все 100% безошибочность ты всё равно не сможешь. А уж 2 девятки или 5 девяток в "надёжности" твоей софтины будет - это чисто вопрос цены - заплатят в 10 раз больше, ну будет на порядок больше малополезных проверок, и даже, возможно "дублирование логики" - т.е. 2-3 РАЗНЫЕ реализации алгоритма (выполненные разными командами разработчиков) с последующей сверкой результатов расчёта по каждому из них
Даже в софте для автопилотов встречаются ошибки, хотя уж там то каких только изощрённых методов повышения надёжности не применяют...
PaulWist
Раньше я привел код триггеров для твоего примера с Продуктом и Алкоголем, ничего там сверх естественного нет, обычный код, правда требующий аккуратности в написании и понимании как работает триггер, то что не все так делают, ну это их право.
Ты привёл пример наглядно показывающий ущербность подхода (а другого там и быть не может - такова суть задачи). Для организации работы с таким образом "защищёнными" таблицами приходится ИСКАЖАТЬ логику работы ПО. Намеренно писать г*нокод - просто потому что система на вход ожидает именно г*но, чтобы его героически исправить и "сделать конфетку". А нормальные, корректные данные она не приемлет!
Грубо говоря, установив на дверь новейший электронный замок ты вынуждаешь пользователя либо выходить в окно, либо заходить в помещение "строго по трое"
Это по меньшей мере странно.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
PaulWist

Сообщений: 14625
Дата регистрации: 01.04.2004
Igor Korolyov
PaulWist
Разница только в том, то в моём понимании состояние данных должно всегда соотвествовать БЛ, в твоём понимании состояние данных может находится в рассогласованном состоянии с БЛ, те (запись в Алкоголе может отсутствовать, тем не менее бука "А" в продукте может находиться).
Ещё раз по буквам. В моём понимании согласованность данных точно такая же как и в твоём.
Только обеспечивается она не "абы-когда" а лишь в согласованных снимках данных - грубо говоря на границе транзакций. И потому нарушение этой согласованности МЕЖДУ 2-мя insert-ами в рамках ОДНОЙ транзакции проблемой не является.
И да, контролировать всю БЛ может, естественно, лишь тот кто управляет транзакцией - да, это может быть ХП "для ввода алкоголя", и даже instead of триггер на специальную "алкогольную" вьюшку. Но никак не триггер на одну (или на обе) из "базовых" таблиц. Может это контролировать и сам клиент. Тем более что при использовании ORM это делает по сути системный код - прикладной разработчик НЕ ПИШЕТ эти insert-ы вручную!

1. УРА!, Ещё в одном месте пришли к одинаковому пониманию

2. Так, ты не перекладывай с "больной головы на здоровую", ты представил структуру данных, для неё я нарисовал поддержку БЛ, ... И ещё добавил, что если выкинуть нафиг "этот дискриминатор", то код упроститься до нельзя, станет прозрачным и красивым, ты же упёрся: "я сам этим дискриминаторм рулю в одной транзакции" и по другому не может быть никогда, вот такой постулат мне совсем не нравится (тем не менее я понимаю твою логику, но сам её стараюсь не использовать, поскольку ... ну сам знаешь).

Igor Korolyov
PaulWist
Дык, в том-то и дело, что ты НИКОГДА не сможешь вытащить ветвь дерева если оно зациклено не на родительский узел, а на один из дочерних узлов одной ветви
1) Смотря как вынимать.

Как не вынимай, у тебя нет ссылок между корневым узлом и дочерними, те пойдя от дочернего (вверх), никогда не достигнешь корня (цикл), пойдя от корня (вниз), никогда не получишь всех потомков, поскольку на корень нет ссылки.

Igor Korolyov
PaulWist
3. Ну вот, ты сам приводишь пример, (шапка и строки) рассогласованности данных с БЛ, с твоей точки зрения это норма для меня нет.
Ё-маё. Да как же НЕТ, когда ДА - когда ты сам страницу назад писал что у тебя строки "согласуются" (как глагол) с шапкой лишь при "утверждении/проведении" документа! Если ДО того как раз "поле в шапке" ни разу не соответствует "полям в строках"! И это "соответствие" НЕВОЗМОЖНО реализовать посредством триггеров. Никак! В принципе невозможно!

Ну-у-у, ты оделяй "мух от котлет", "проект данных" не является данными, тут ты совершенно прав, что для "проекта данных" нельзя построить никакой БЛ, ... у меня даже в мыслях не было, что ты говоришь о "проекте данных", ...

Igor Korolyov
PaulWist
И это правильно, ты должен предусмотреть все возможные ситуации, а как ты это сделаешь - дело десятое.
Зачем? Это в технологическом софте цена ошибки велика, а в рядовом бухгалтерско-учётном - мизерна. И удорожать софт в 3-4 раза совершенно нецелесообразно. При том что гарантировать на все 100% безошибочность ты всё равно не сможешь. А уж 2 девятки или 5 девяток в "надёжности" твоей софтины будет - это чисто вопрос цены - заплатят в 10 раз больше, ну будет на порядок больше малополезных проверок, и даже, возможно "дублирование логики" - т.е. 2-3 РАЗНЫЕ реализации алгоритма (выполненные разными командами разработчиков) с последующей сверкой результатов расчёта по каждому из них
Даже в софте для автопилотов встречаются ошибки, хотя уж там то каких только изощрённых методов повышения надёжности не применяют...

Ну, бросать юзера по "танки" системных сообщений, мне кажется не совсем разумно, хотя со временем они к этому привыкают, всё таки получить сообщение типа: "Заполните дату документа" куда приятнее, чем Field date dos'n accept null.

Igor Korolyov
PaulWist
Раньше я привел код триггеров для твоего примера с Продуктом и Алкоголем, ничего там сверх естественного нет, обычный код, правда требующий аккуратности в написании и понимании как работает триггер, то что не все так делают, ну это их право.
Ты привёл пример наглядно показывающий ущербность подхода (а другого там и быть не может - такова суть задачи). Для организации работы с таким образом "защищёнными" таблицами приходится ИСКАЖАТЬ логику работы ПО. Намеренно писать г*нокод - просто потому что система на вход ожидает именно г*но, чтобы его героически исправить и "сделать конфетку". А нормальные, корректные данные она не приемлет!
Грубо говоря, установив на дверь новейший электронный замок ты вынуждаешь пользователя либо выходить в окно, либо заходить в помещение "строго по трое"
Это по меньшей мере странно.

Уже ответил, надо выкинуть это "дискриминатор" и всё, но тогда платформа разработки не сумеет работать.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
PaulWist
если выкинуть нафиг "этот дискриминатор", то код упроститься до нельзя, станет прозрачным и красивым
Это лишь первый пришедший в голову "рабочий" пример имеющейся бизнес-связи между 2-мя таблицами. Можно подобрать и другой. К примеру связка таблиц "клиент - физлицо" с правилами "для физлица ИНН необязателен, для конторы - обязателен" или "для физлица статус не может быть vip, а статус gold могут иметь только совершеннолетние, несудимые граждане РФ".
Т.е. любое бизнес-правило затрагивающее поля из обеих таблиц мгновенно рушит всю твою систему "на триггерах".
При том что оно элементарно, даже без малейшей тени сомнения реализуется в любом языке и любой системе программирования Если просто выкинуть на свалку одну устаревшую догму
PaulWist
Как не вынимай, у тебя нет ссылок между корневым узлом и дочерними, те пойдя от дочернего (вверх), никогда не достигнешь корня (цикл), пойдя от корня (вниз), никогда не получишь всех потомков, поскольку на корень нет ссылки.
Что-то ты не договариваешь...
В твоём примере:
1) нет никакого "корня", поскольку имеется цикл (все элементы равноправны).
2) начав с любого его (цикла) элемента можно получить все остальные элементы - лишь бы "метод получения" не зацикливался.
Приведи пример (просто пары id/parent_id и требуемое "действие прохода по иерархии") с "неправильным" поведением. Да, ещё надо учитывать что в такой схеме можно интерпретировать связь как "направленную", или как ненаправленную (сравняв id и parent_id в "правах" - тут "классические" иерархические запросы уже не подойдут, т.к. 1-2 и 2-3 должны в таком случае заодно "интерпретироваться" и как 3-2 и 2-1). Т.е. грубо говоря для цепочки 1-2-3 нельзя "считая от корня 3" получить элементы 2 и 1 - если не объявить связи "ненаправленными" - но тогда это уже будет терминологически не "корень и ветви дерева", а просто "узлы и рёбра неориентированного графа"...

PaulWist
Ну-у-у, ты оделяй "мух от котлет", "проект данных" не является данными, тут ты совершенно прав, что для "проекта данных" нельзя построить никакой БЛ, ... у меня даже в мыслях не было, что ты говоришь о "проекте данных"
В БД нет никаких "проектов данных". Там есть таблицы, записи и поля с данными в оных
И если рассуждать типа "вот тут у нас данные, а тут не данные, потому я их не проверяю", то уж извини, но это даже ещё более "мусорный" вариант нежели мой пример с 2-мя последовательно выполняемыми insert-ами. У меня хотя бы этот "мусор" не видит никто вовне транзакции, а у тебя он всем доступен - и без "сакрального знания" о том что ежели state=0 то это мусор а ежели state=1 то "данные" - никак не обойтись
Заметь - я не говорю что так делать нельзя - это допустимое компромиссное решение в ряде случаев. Но тут вспоминается старинный анекдот:
- И эти люди запрещают мне ковырять пальцем в носу!

PaulWist
всё таки получить сообщение типа: "Заполните дату документа" куда приятнее, чем Field date dos'n accept null.
Кстати, это обычно проверяют "чисто на клиенте", задолго до того как пошлют сию запись на сервер. И "долбить" сервер "глупыми" записями чисто для того чтобы получить "красивый" текст ошибки - я считаю это неразумно...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
PaulWist

Сообщений: 14625
Дата регистрации: 01.04.2004
Igor Korolyov
PaulWist
если выкинуть нафиг "этот дискриминатор", то код упроститься до нельзя, станет прозрачным и красивым
Это лишь первый пришедший в голову "рабочий" пример имеющейся бизнес-связи между 2-мя таблицами. Можно подобрать и другой. К примеру связка таблиц "клиент - физлицо" с правилами "для физлица ИНН необязателен, для конторы - обязателен" или "для физлица статус не может быть vip, а статус gold могут иметь только совершеннолетние, несудимые граждане РФ".
Т.е. любое бизнес-правило затрагивающее поля из обеих таблиц мгновенно рушит всю твою систему "на триггерах".
...

1. Ты это "пальцем покажи", про "клиент - физлицо", скрипт таблиц, а то не понял.

2. Поскольку ты скрипты таблиц не привёл и если правильно понял структуру данных, то код такой:

create table People (ID int, Status_ID int, dDateBirth date )
create trigger IU_People on People
after insert, Update
as
begin
-- проверяем на Vip статус
if exists(select 1 from Inserted People
inner join Status
on People.Status_ID = Status.ID
and Status.Name = 'Vip'
begin
-- генерим ошибку, "Для физ. лица запрещен статус VIP"
end
-- Проверяем на возраст и судимость
if exists(select 1 from Inserted People
inner join Status
on People.Status_ID = Status.ID
and Status.Name = 'Gold'
and (FunctionAge.IsOK = 0 or FunctionCourt.IsOK = 1)
outer apply FunctionAge(People.ID) -- возвращаем совершеннолетие = 1
outer apply FunctionCourt(People.ID) -- вычисляем судимость = 1
begin
-- генерим ошибку, "Для физ. лица запрещен статус GOLD", поскольку
либо возраст, либо судимость или то и другое.
end
end

Как-то так, а что здесь сверхестественного, элементарный код проверки, в чем для тебя загвоздка?

Igor Korolyov
PaulWist
Как не вынимай, у тебя нет ссылок между корневым узлом и дочерними, те пойдя от дочернего (вверх), никогда не достигнешь корня (цикл), пойдя от корня (вниз), никогда не получишь всех потомков, поскольку на корень нет ссылки.
Что-то ты не договариваешь...
В твоём примере:
1) нет никакого "корня", поскольку имеется цикл (все элементы равноправны).
2) начав с любого его (цикла) элемента можно получить все остальные элементы - лишь бы "метод получения" не зацикливался.
Приведи пример (просто пары id/parent_id и требуемое "действие прохода по иерархии") с "неправильным" поведением. Да, ещё надо учитывать что в такой схеме можно интерпретировать связь как "направленную", или как ненаправленную (сравняв id и parent_id в "правах" - тут "классические" иерархические запросы уже не подойдут, т.к. 1-2 и 2-3 должны в таком случае заодно "интерпретироваться" и как 3-2 и 2-1). Т.е. грубо говоря для цепочки 1-2-3 нельзя "считая от корня 3" получить элементы 2 и 1 - если не объявить связи "ненаправленными" - но тогда это уже будет терминологически не "корень и ветви дерева", а просто "узлы и рёбра неориентированного графа"...

...

Вот скрипт, который я привел в предыдущем сообщении (видимо ты его невнимательно посмотрел):

use tempdb
go
create table test
(
ID int not null Primary key,
Parent_ID int FOREIGN KEY
REFERENCES test(ID )
)
insert into test (ID, Parent_ID) values (1, null)
insert into test (ID, Parent_ID) values (2, 1)
insert into test (ID, Parent_ID) values (3, 2)
-- замыкаем дерево НА ПЕРВЫЙ дочерний узел, получается "кольцо"
update test set Parent_ID = 3
where ID = 2
select * from Test

Обращаю внимание, что ветвь замыкается для ID = 2, те получаем:

Цитата:
ID, Parent_ID
1 , Null
2 , 3
3 , 2


как видишь цикл замкнулся на ID = 2, для него родителем стал ID = 3, для которого родителем опять является ID = 2.

Поэтому, как бы ты не исхитрялся пойдя от ID = 1 поучить записи с ID = 2, 3, получишь одну запись.
Или пойдя от ID = 2 или ID = 3 получишь две записи, НО никогда не дойдешь до ID = 1, поскольку связь родитель-дочка разорвана.

Igor Korolyov
PaulWist
Ну-у-у, ты оделяй "мух от котлет", "проект данных" не является данными, тут ты совершенно прав, что для "проекта данных" нельзя построить никакой БЛ, ... у меня даже в мыслях не было, что ты говоришь о "проекте данных"
В БД нет никаких "проектов данных". Там есть таблицы, записи и поля с данными в оных
И если рассуждать типа "вот тут у нас данные, а тут не данные, потому я их не проверяю", то уж извини, но это даже ещё более "мусорный" вариант нежели мой пример с 2-мя последовательно выполняемыми insert-ами. У меня хотя бы этот "мусор" не видит никто вовне транзакции, а у тебя он всем доступен - и без "сакрального знания" о том что ежели state=0 то это мусор а ежели state=1 то "данные" - никак не обойтись
Заметь - я не говорю что так делать нельзя - это допустимое компромиссное решение в ряде случаев. Но тут вспоминается старинный анекдот:
- И эти люди запрещают мне ковырять пальцем в носу!
...

Э-э-э, брат, объясни мне, как ты заполняешь документ, когда часть данных на момент заполнения ещё неизвестна? ставишь наобум обязательные атрибуты, а потом по ним можно сделать отчет? как ты узнаешь что в этом доке всё правильно заполнено, а другом нет?

А если не ставишь/заносишь в таблицы обязательные атрибуты, то чем твои данные отличаются от моих?

У меня то есть признак при stаtus = 0 я их не проверяю (не заношу в связанные таблицы, игнорирую почти всегда при отчетах), а при status = 1 проходит полный цикл БЛ, ... более того такие данные (ststus = 1) нельзя уже удалить опять же по БЛ и эту БЛ обеспечивают триггеры, констренты.

Igor Korolyov
PaulWist
всё таки получить сообщение типа: "Заполните дату документа" куда приятнее, чем Field date dos'n accept null.
Кстати, это обычно проверяют "чисто на клиенте", задолго до того как пошлют сию запись на сервер. И "долбить" сервер "глупыми" записями чисто для того чтобы получить "красивый" текст ошибки - я считаю это неразумно...

Согласен неудачнй пример для БД, более наглядный это FK, что лучше получить "Delete Referece error FK_00012344 for table MyTable" или "Нельзя удалять что-то там, поскольку существует остаток на складе", или ты на клиенте такие вещи проверяешь? если да, то расскажи как?


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
pasha_usue

Сообщений: 3650
Откуда: Е-бург
Дата регистрации: 06.10.2006
PaulWist
Э-э-э, брат, объясни мне, как ты заполняешь документ, когда часть данных на момент заполнения ещё неизвестна? ставишь наобум обязательные атрибуты, а потом по ним можно сделать отчет? как ты узнаешь что в этом доке всё правильно заполнено, а другом нет?
На момент когда пользователь заносит документ, все неизвестные для этого пользователя определены. Если это не так, то сущность документа выделена некорректно.

Другой вопрос, пользователь для себя может считать, что документ рано принимать к учёту, он с ним продолжает работать. Тогда да, тогда есть неизвестные, как для пользователя, так и для системы.
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Где-то выше было хорошее замечание, что неплоха бы возможность ввода неполного документа, типа "черновик". Тогда система должна позволять ввести вообще пустой документ, типа APPEND BLANK в фоксе. Но это наверное нарушает красоту проверяльщиков-триггеров ввода в БД, и тогда выходит, что ХП на стороне БД нельзя сделать заточенными на ввод только правильного документа, т.к. возможны "черновики"... (я хоть немного улавливаю нить спора?)
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
PaulWist

Сообщений: 14625
Дата регистрации: 01.04.2004
pasha_usue
На момент когда пользователь заносит документ, все неизвестные для этого пользователя определены. Если это не так, то сущность документа выделена некорректно.

Не совсем, я уже приводил пример доступного лимита, когда договорились, что купят на 100р, а вот что конкретно и по какой цена ещё неизвестно.

Или принимают работника, с собой у него сейчас нет , например дипломов о курсах повышения квалификации, их можно внести "потом".

pasha_usue
Другой вопрос, пользователь для себя может считать, что документ рано принимать к учёту, он с ним продолжает работать. Тогда да, тогда есть неизвестные, как для пользователя, так и для системы.

Это само собой разумеется.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
PaulWist

Сообщений: 14625
Дата регистрации: 01.04.2004
of63
Где-то выше было хорошее замечание, что неплоха бы возможность ввода неполного документа, типа "черновик". Тогда система должна позволять ввести вообще пустой документ, типа APPEND BLANK в фоксе. Но это наверное нарушает красоту проверяльщиков-триггеров ввода в БД, и тогда выходит, что ХП на стороне БД нельзя сделать заточенными на ввод только правильного документа, т.к. возможны "черновики"... (я хоть немного улавливаю нить спора?)

1. Наоборот, до тех пор пок не поставлен признак закрыт/принят/проведён итп, то триггер из себя представляет просто goto EndTrigger, те док. представляет собой "черновик"

2. ХП вообще не знает, какой док. черновик, какой "правильный", ХП "тупо" апдейтит поля таблиц.

3. Мысль ловишь на лету


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
PaulWist
1. Ты это "пальцем покажи", про "клиент - физлицо", скрипт таблиц, а то не понял.
2. Поскольку ты скрипты таблиц не привёл и если правильно понял структуру данных, то код такой:
Поле Status_ID в таблице Client - связанной с People по Id. Как ранее Product был связан с Alcohol. И да, никаких "вражьих дискриминаторов" - чисто бизнес-значимые поля.
Естественно, при создании сущности тоже будет 2 подряд идущих команды Insert. При модификации - 2 update-а. Для простоты не рассматриваем "глупый случай" когда клиент - не-физлицо вдруг становится физлицом и наоборот.
PaulWist
в чем для тебя загвоздка?
В проверке полей из РАЗНЫХ таблиц, изменяемых РАЗНЫМИ DML командами. Проверке именно триггером. Т.к. "просто ХП" может это без проблем сделать, потом выполнив 2 уже "непроверяемых" insert-а.
PaulWist
Обращаю внимание, что ветвь замыкается для ID = 2, те получаем:
Цитата:
ID, Parent_ID
1 , Null
2 , 3
3 , 2

как видишь цикл замкнулся на ID = 2, для него родителем стал ID = 3, для которого родителем опять является ID = 2.
Ну нормально. Несвязный граф. "Одиночная" вершина (aka узел) 1 и небольшой цикл 2-3.
Даже не поленюсь "нарисовать"

[attachment 27286 graph1.png]

PaulWist
Поэтому, как бы ты не исхитрялся пойдя от ID = 1 поучить записи с ID = 2, 3, получишь одну запись.
Или пойдя от ID = 2 или ID = 3 получишь две записи, НО никогда не дойдешь до ID = 1, поскольку связь родитель-дочка разорвана.
С какого это перепугу "пойдя от 1" я должен получить 2 или 3 или вообще что-либо, если это отдельная независимая вершина - отдельный (вырожденный) подграф, или такое же отдельное вырожденное "дерево"?
С чего бы это пойдя из цикла 2-3 (неважно начиная с 2 или с 3) я должен попасть к 1? Где логика, где разум

Никакой связи между ними НЕТ - и это совершенно нормально и логично - и никаких проблем не вызывает. Вот любое телодвижение которое для таких данных каким-то "волшебным" образом соединит 1 с "2-3" - будет очевидно ошибочным. Т.к. явно противоречит хранящимся в таблице данным
Более того, если наши "бизнес-правила" запрещают держать в таблице несвязный граф, запрещают вообще граф а требуют исключительно "дерево" - при том возможно ещё и с "ограничением глубины вложенности" - ну да, это потребует проведения определённых проверок кодом модификации этой таблицы. Одного самосвязанного FK тут явно недостаточно.
Я полагаю что в общем случае такая проверка потребует извлечения ВСЕХ записей из таблицы (по "частичной" модификации невозможно определить что она нарушает или не нарушает) - и я не уверен что рекурсивный CTE является для этого самым оптимальным решением...
Более того, в некоторых случаях может оказаться что вообще "дерево в 1 таблице" не нужно - а нужно тупо сделать 3-4 плоские таблицы с "обычными" связями между ними. Группа/подгруппа/блок/деталь.
Кстати, мне вот интересно каким образом ты для подобной структуры будешь триггером проверять что кусок иерархии не обрывается не дойдя до уровня "детали" Ещё один вариант для демонстрации проблемы "проверок межтабличных связей".

PaulWist
Э-э-э, брат, объясни мне, как ты заполняешь документ, когда часть данных на момент заполнения ещё неизвестна? ставишь наобум обязательные атрибуты, а потом по ним можно сделать отчет? как ты узнаешь что в этом доке всё правильно заполнено, а другом нет?
Начнём с простого. Я не заполняю "непойми что" - вот Владимир Максимов - да. Он, вероятно как и ты, сохраняет абсолютно произвольный мусор в таблицах шапка-детали-поддетали, и только при установлении статуса "готово" проверяет этот мусор "по полной программе". Т.е. у него нет никаких констрейнов not null, никаких check-ов, возможно нет и foreign key констрейнов (т.к. в этом случае реальный "мусор" будет мешать и работе со справочником, и работе с таблицами ссылающимися на эти полу-мусорки, а сделать декларативный FK работающий лишь с "хорошими" записями но пропускающий "плохие" невозможно в известных мне СУБД). Наверняка нет и триггеров, т.к. смысла реализовывать БЛ в триггере, если она должна срабатывать лишь при определённом "действии" - установлении статуса - я лично не вижу. Хотя это уже не принципиальный момент.
Мне приходилось работать лишь с документами где ИЗВЕСТНЫ все обязательные данные. И нужды сохранять мусор "для последующего доввода" у меня не было. Впрочем, если бы такая надобность появилась, я вряд ли стал бы использовать для этого "основные" таблицы. Можно сохранять неготовый мусор в тривиальную XML и даже не в БД, можно в отдельные таблицы (как раз безо всяких проверок/констрейнов). Эти альтернативы, как по мне, ничем не хуже превращения основной таблицы в полу-мусорку - где часть записей "хорошая", а часть - нет. Если при том ещё для выяснения статуса хорошая запись или нет нужно обращаться к другой таблице (т.е. хранить статус только в "шапке") - да ещё и через 1-2 уровня (документы бывают и сложные/массивные) - ну это весьма непроизводительное и в общем "плохое" решение, как по мне...
PaulWist
А если не ставишь/заносишь в таблицы обязательные атрибуты, то чем твои данные отличаются от моих?
Если этот атрибут "обязательный", то набор циферок БЕЗ него не является документом. Если же можно сохранить документ и без него - то он НЕ обязателен. Всё элементарно
PaulWist
У меня то есть признак при stаtus = 0 я их не проверяю (не заношу в связанные таблицы, игнорирую почти всегда при отчетах), а при status = 1 проходит полный цикл БЛ, ... более того такие данные (ststus = 1) нельзя уже удалить опять же по БЛ и эту БЛ обеспечивают триггеры, констренты.
Тут проверяем, тут не проверяем, тут рыбу заворачивали - "и они ещё борются за звание дома высокой культуры быта"
"Отключаемая" проверка по сути своей не является проверкой.
Все эти статусы "ты туда не ходи, ты сюда ходи" - это весьма спорный костыль. Сколько г*на вылазит всегда при использовании подобных решений (конечно же они и у нас применяются - всякие "неактивности", "прятание записей" и те же самые "статусы документов") - тут забыли нужный фильтр сделать. Тут напротив - действующий фильтр "выкинул" нужные (исторические, к примеру) записи...
Нет никакой "серебряной пули", как говорят англичане - любое выбранное решение будет иметь как плюсы так и минусы, и очень серьёзные порой. Вот так и крутишься, выбирая из двух зол меньшее
Но ежели бы мне сказали что выбирать нельзя - только "вот так ходи" - ну я бы не сработался с такими начальниками


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
PaulWist
Не совсем, я уже приводил пример доступного лимита, когда договорились, что купят на 100р, а вот что конкретно и по какой цена ещё неизвестно.
Пример надуманный. Я иду в магазин и оставляю на кассе 100р - они даже чек мне пробивают, поди и лишь потом я буду искать чего ж на 100р купить
Но даже если не обсуждать его СМЫСЛ.
Выделяем понятие "лимит" - сохраняем его ОТДЕЛЬНО от "покупок". Всё. Правила соблюдены, никаких "черновиков" не требуется. Есть сущность и она совершенно корректна сама по себе! Потом будет создана другая сущность, связанная с этой - скажем "использование лимита на покупки".
Как видишь нет решительно никаких проблем с "разделением".
Проблема будет лишь у того кто пытается всё это в единой железобетонно-связанной куче хранить и использовать.

PaulWist
Или принимают работника, с собой у него сейчас нет , например дипломов о курсах повышения квалификации, их можно внести "потом".
И этот "диплом" обязательный реквизит? Без него никого на работу не принимают А так же без жены, детей, личного автотранспорта, воинского/или белого билета, открытой визы в Гондурас и справки от гинеколога (ога, независимо от пола "абитуриента").

Может быть кто-то просто смешал в кучу разные сущности, да ещё и объявил некоторые из них "обязательными"
Вот то что сущность диплом, связанная с сущностью "соискатель" (или там сразу "работник" - терминология тоже важна) должна иметь (к примеру) обязательные реквизиты "номер диплома", "название выдавшей организации" и "дата получения" - тут я не поспорю - но и вводить "только номер" т.к. самого диплома физически на руках нет - это глупость и вредность. Вот принесёт бумажку - все обязательные реквизиты и заполнятся. А если уж неймётся кадровику отметить какого ценного сотрудника он подыскал - пусть в каких-нить freeform примечаниях все эти "бонусы" которые документально не подтверждены и не могут быть помещены "формально" в БД и пишет.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
() У меня это пометка договора "черновик", или "договор заключен, но еще не жействует". Кстати бывает важно, когда именно клиент заключил жоговор, но не подтвердил. Может наличие поля "состояние записи" (например: черновик/действует/закончено) поможет?

Точно уверен, что иногда "недоданные" имеют право быть в БД, по жизни, и описывать их механику, на языке триггеров, или T-SQL - нереально, их алгороитм ...етм, меняется ежегодно, если не чаще. Поэтому я за БД - как набор таблиц, без особого программного кода. Просто реальная жизнь не предполагает структуры (и кода), заданного более чем на 1 год.
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Заключён/Действует/Аннулирован/Завершён - это БИЗНЕС-понятия "состояний". Они логичны и нормальны.

"черновик" - это нечто не имеющее вообще отношения к бизнес-логике. Как фоксовая пометка записи на удаление.
Служебное поле - костыль, работающий иногда чуть лучше других костылей для решения "неразрешимой" проблемы - совмещения взаимоисключающих параграфов "в базе должен быть порядок", "я хочу сохранять то г*но что ввёл - чего это ваша плохая прога меня ругает матом".


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Игорь, но это приходится хранить, позволять хранить, и даже снабжать некоторыми признаками (кто ввел, когда, по какой причине). Я хотел обратить внимание именно на то, что "плохое" состояние БД может представлять собой некоторое псевдо-"состояние" (например, это же есть в 1С "проведен/не проведен").
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
pasha_usue

Сообщений: 3650
Откуда: Е-бург
Дата регистрации: 06.10.2006
PaulWist
pasha_usue
На момент когда пользователь заносит документ, все неизвестные для этого пользователя определены. Если это не так, то сущность документа выделена некорректно.
Не совсем, я уже приводил пример доступного лимита, когда договорились, что купят на 100р, а вот что конкретно и по какой цена ещё неизвестно.
Это о чём я и говорил. Сущность документа в бизнес-процессе выделена неверно. Должен быть документ лимит-закупа (проект закупа), который может иметь расшифровку, а может не иметь. На этом документе участники процесса обговаривают, сколько денег готовы потратить. А потом происходит хозяйственная операция фактического закупа, для которой основанием может являться выделенный лимит. Или несколько таких операций.

PaulWist
Или принимают работника, с собой у него сейчас нет , например дипломов о курсах повышения квалификации, их можно внести "потом".
Это не обязательная информация для кадрового учёта. Иногда требуется знать дату подтверждения квалификации и разрядности. Во всех остальных случаях, это зона ответственности ОК, а не программы.
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
pasha_usue

Сообщений: 3650
Откуда: Е-бург
Дата регистрации: 06.10.2006
of63
() У меня это пометка договора "черновик", или "договор заключен, но еще не жействует". Кстати бывает важно, когда именно клиент заключил жоговор, но не подтвердил. Может наличие поля "состояние записи" (например: черновик/действует/закончено) поможет?
В праве есть понятие неотъемлемые реквизиты договора. Чаще всего это Субъекты договора, Объект(ы) договора, Дата составления, Признаки (дата) возникновения обязательств, Номер договора и, в большинстве случаев, суммовая оценка договора. Вот пока эти сущности не определены, это мусор с точки зрения как базы, так и юриста. Это - черновик, или шаблон. Всё остальное - уже договор, который имеет свой жизненный цикл. Он может быть проектом, может быть заключенным и ожидать, когда наступят те или иные обязательства по договору, а может быть уже отработанным, но в пределах исковой давности.

И да. Означенные выше неотъемлемые реквизиты могут быть как очень простыми (1 поле), так и очень сложными и разветвлёнными.



Исправлено 1 раз(а). Последнее : pasha_usue, 21.03.17 06:33
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Видимо, не "дата составления", а "дата подписания" (дата регистрации)?
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
pasha_usue

Сообщений: 3650
Откуда: Е-бург
Дата регистрации: 06.10.2006
Simple777
Видимо, не "дата составления", а "дата подписания" (дата регистрации)?
Вот в шапке договора сверху написаны дата и номер. Это то что я назвал дата составления. А вот дата подписания может быть другой (она в конце договора идёт). Вообще, в этих датах путаются и юристы в том числе, поэтому страхуются и стараются, чтоб эти две даты совпадали.

Ну, а дата и условия возникновения обязательств по договору, это нечто третье. Опять же. Это может быть набор дат и условий для каждой из сторон.
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Это, конечно, отвлечение от "генеральной линии партии", но...

Вверху, в шапке договора, должна стоять не дата составления, а дата регистрации договора юридической или иной полномочной службы. "Теоретически" дата регистрации у сторон договора может быть разной. Кстати, вопрос насчет дат отнюдь не праздный. Бизнес-логика должна учитывать даже самое невероятное сочетание дат (кроме явно фейковых). Иначе рано или поздно попадется договор, который не получится ввести в информационную систему.
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
of63
возможность ввода неполного документа, типа "черновик". Тогда система должна позволять ввести вообще пустой документ, типа APPEND BLANK в фоксе. Но это наверное нарушает красоту проверяльщиков-триггеров ввода в БД, и тогда выходит, что ХП на стороне БД нельзя сделать заточенными на ввод только правильного документа, т.к. возможны "черновики"
Вот у меня есть док, который проходит кучу стадий.
На вскидку. Приехала машина, предположительно возьмет то то, столько то, потом машина выезжает, и уже конкретно что и сколько, потом оплата, потом ее выпускают.
Вкратце, и самый простой случай.
И всем этим рулит одна ХП.
Все можно сделать.
Но эта ХП - ужас!)))
Главное, при изменении каких то БП, она в первую очередь и правится.
Все можно сделать. Все. И везде.
Но настаивать, что так единственно правильно, я бы не решился)

В споре Игоря и Паши, мне ближе позиция Игоря, но реализации, больше как у Паши.))


------------------
Ratings: 0 negative/0 positive
Re: как программно сделать приватную датасесию
PaulWist

Сообщений: 14625
Дата регистрации: 01.04.2004
pasha_usue
PaulWist
pasha_usue
На момент когда пользователь заносит документ, все неизвестные для этого пользователя определены. Если это не так, то сущность документа выделена некорректно.
Не совсем, я уже приводил пример доступного лимита, когда договорились, что купят на 100р, а вот что конкретно и по какой цена ещё неизвестно.
Это о чём я и говорил. Сущность документа в бизнес-процессе выделена неверно. Должен быть документ лимит-закупа (проект закупа), который может иметь расшифровку, а может не иметь. На этом документе участники процесса обговаривают, сколько денег готовы потратить. А потом происходит хозяйственная операция фактического закупа, для которой основанием может являться выделенный лимит. Или несколько таких операций.

Тут вопрос философский, такая модель бизнеса (именно так он исторически построился), да логически это две разных сущности, физически это один набор таблиц отличающихся признаком "проведения".

pasha_usue
PaulWist
Или принимают работника, с собой у него сейчас нет , например дипломов о курсах повышения квалификации, их можно внести "потом".
Это не обязательная информация для кадрового учёта. Иногда требуется знать дату подтверждения квалификации и разрядности. Во всех остальных случаях, это зона ответственности ОК, а не программы.

С какой стороны посмотреть - это по большому счёту деньги, те когда, на сколько и в каком количестве "посылать" на курсы аттестации/переквалификации/итп, те такая инфа становится обязательной!


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 19 (Гостей: 19)

© 2000-2024 Fox Club 
Яндекс.Метрика