powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Триггер или многотабличное ограничение?
8 сообщений из 8, страница 1 из 1
Триггер или многотабличное ограничение?
    #35020811
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предисловие.
Данная задача уже решена мною в Аксессе, с использованием VBA. Но, сами понимаете, со временем скорость работы приложения, разработанного в Аксессе падает, по мере увеличения базы и количества юзеров, коннектящихся к ней. Уточняю - изначально я сделал не ADP-проект, а простое клиент-серверное приложение (на локальных компах установлен mdb-файл клиент, а на серваке, в общей папке лежит mdb-файл с таблами, к которому все и коннектятся). Сами видите - вариант приложения наихудший но тем не менее прошу строго не судить - это первое приложение, относительно серьезное, которое я написал... Создать из имеющейся базы ADP-проект не вариант, т.к. в коде я везде использовал модель DAO, а MS SQL Server ее не приемлет. Ему нужна ADO. Т.о. Проще написать новую прогу. Чем я сейчас и занимаюсь.
Так как возможности MS SQL Server намного выше возможностей Аксесса - хочу их использовать по максимуму. В первую очередь - все проверки данных должен проверять сам MS SQL Server, а не написанный мною программный код, следовательно создаю все необходимые чеки, триггеры и... assertion (о нем речь далее).
Эскиз ситуации.
Тематика: Строительство
Общая информация.
Для того, чтобы посчитать стоимость строительства объекта, составляется смета .
Смета, в свою очередь, состоит из разделов (т.е. общестроительные работы, монтажные работы, сантехнические работы и т.п.).
Каждый раздел содержит в себе конкретный набор работ.
И наконец - работа содержит в себе определенный набор строительных материалов , которые нужно заказать и купить, дабы их можно было вовлечь в производство. Далее идет интересный момент:
Для того, чтобы заказать материал, нужно создать заявку (на материалы).
Заявка должна содержать позиции материалов (взятых из сметы - т.е. заказать можно только те наименования материалов, которые присутствуют в смете) но это, понятное дело, еще не все.
Заказать материал можно не более остатка, (разницы количества данного материала в составе сметы и количества уже проведенного др. заявками). Т.о. необходимо осуществить такую проверку.
***********************************************
Вижу 2 варианта организации этой проверки:
1. Самый простой - триггеры
2. Теоретически более быстрый (т.к. check (во всяком случае табличный) работает быстрее триггера) - многотабличное ограничение (CREATE ASSERTION ...)
Выкладываю принтскрин схемы (фрагмент) и исходники таблов (дабы видны были ограничения таблов). Заодно показываю "стадию" на которой я пока что запнулся на процессе написания многотабличного ограничения...

А вопрос сейчас такой:
Являются ли многотабличные ограничения так же более быстрые как и обычные check, или же не стоит заморачиваться - писать триггер?
...
Рейтинг: 0 / 0
Триггер или многотабличное ограничение?
    #35020813
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Триггер или многотабличное ограничение?
    #35020822
iSestrin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CREATE ASSERTION - это в какой субд вы почерпнули?
...
Рейтинг: 0 / 0
Триггер или многотабличное ограничение?
    #35020831
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
--Таблица смет
create table info.Estimate
(estimateID		int identity	primary key		not null,
estimateNomber	int								not null,
estimateDate	datetime	default getdate()	not null,
estimateOwner varbinary( 85 ) DEFAULT SUSER_SID()	not null,
estimateName	varchar( 255 )					not null,
estimateNik		varchar( 50 )						not null,
inProject			bit	default  0 				not null,
blocked				bit default  0 				not null,
ObjectChargeID	int								null
foreign key references	info.ObjectCharges(ObjectChargeID),
ContractID		int								not null
foreign key references info.Contracts(ContractID),
constraint Estimate_ContractID_estimateNomber unique(ContractID,estimateNomber),
constraint Estimate_ContractID_estimateName unique(ContractID,estimateName),
constraint Estimate_ContractID_estimateNik unique(ContractID,estimateNik)
)
go
--разделы смет
create table info.Parts
(partID			int identity	primary key		not null,
PartNomber		int								not null,
PartName		varchar( 255 )					not null,
ObjectChargeID	int								null
foreign key references	info.ObjectCharges(ObjectChargeID),
estimateID		int								not null
foreign key references	info.Estimate(estimateID),
constraint Parts_estimateID_PartNomber unique (estimateID,PartNomber),
constraint Parts_estimateID_PartName unique (estimateID,PartName)
)
go
--наборы работ сметы
create table info.Works
(WorkID				int identity		primary key			not null,
WorkNomber			int										not null,
WorkName			varchar( 255 )							not null,
WorkED				varchar( 50 )								not null,
WorkValue			decimal		default  0 					not null,
WorkCost			money		default  0 					not null,
WorkSumma			as WorkValue*WorkCost,
WorkFixedSumma		money		default  0 					not null,
WorkTZ				decimal		default  0 					not null,
WorkTzsumma			as WorkTZ*WorkValue,
WorkNotes			varchar( 255 )							null,
Subcontractor		bit default  0 							not null,
WorkKey				as WorkName + '_' + WorkED,
partID				int										not null
foreign key references info.Parts(partID),
constraint Works_WorkCost_WorkFixedSumma		check((WorkCost>= 0  and WorkFixedSumma= 0 ) or
(WorkCost> 0  and WorkFixedSumma> 0 )),
constraint Works_WorkTZ							check(WorkTZ>= 0 ),
constraint Works_WorkNomber						check(WorkNomber> 0 ),
constraint Works_WorkValue						check(WorkValue>= 0 ),
constraint Works_WorkNomber_partID				unique(partID,WorkNomber),
)
go
--материалы в составе работ сметы
---postavschik - поставщик. принимает 3 варианта значений:
--1 Отдел снабжения
--2 Прорабы
--3 Заказчик
create table info.Materials
(MaterialID				int identity	primary key		not null,
MaterialName			varchar( 255 )					not null,
MaterialMarka			varchar( 50 )						not null,
MaterialED				varchar( 50 )						not null,
MaterialValue			decimal	default  0 				not null,
MaterialCost			money	default  0 				not null,
MaterialSumma			as MaterialCost*MaterialValue,
MaterialFixedSumma		money		default  0 			not null,
MaterialNotes			varchar( 255 )					null,
MaterialKey1			as MaterialName + '_' + MaterialMarka + '_' + MaterialED,
MaterialKey2			as MaterialName + '_' + MaterialMarka + '_' + MaterialED  + '_' + isnull(MaterialNotes,' '),
WorkID				int								not null		
foreign key references info.Works(WorkID),
postavschik			tinyint	default  1 				not null
constraint	Materials_postavschik check(postavschik= 1  or
postavschik= 2  or postavschik= 3 ),
constraint Materials_MaterialCost_MaterialFixedSumma		check((MaterialCost>= 0  and MaterialFixedSumma= 0 ) or
(MaterialCost> 0  and MaterialFixedSumma> 0 ))
)
go
и
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
--Заявки на материалы
create table building.ZvMaterials
(
zvMaterialID		int identity	primary key		not null,
zvMaterialNomber	int								not null,
zvMaterialDate		datetime	default getdate()	not null,
zvMaterialOwner varbinary( 85 ) DEFAULT SUSER_SID()	not null,
zvYear				as year(zvMaterialDate),
estimateID			int								not null
foreign key references	info.Estimate(estimateID),
constraint ZvMaterials_zvMaterialNomber_Year unique(zvMaterialNomber,zvYear)
)
--Записи заявки на материалы
create table building.ZvRecMaterials
(zvRecMaterialID				int identity	primary key		not null,
zvRecMaterialName			varchar( 255 )					not null,
zvRecMaterialMarka			varchar( 50 )						not null,
zvRecMaterialED				varchar( 50 )						not null,
zvRecMaterialValue			decimal	default  0 				not null,
zvRecMaterialCost			money	default  0 				not null,
zvRecMaterialSumma			as zvRecMaterialCost*zvRecMaterialValue,
zvRecMaterialNotes			varchar( 255 )					null,
zvRecMaterialKey1			as zvRecMaterialName + '_' + zvRecMaterialMarka + '_' + zvRecMaterialED,
zvRecMaterialKey2			as zvRecMaterialName + '_' + zvRecMaterialMarka + '_' + zvRecMaterialED  + '_' + 
isnull(zvRecMaterialNotes,' '),
zvMaterialID				int								not null		
foreign key references building.ZvMaterials(zvMaterialID)
)
go
...
Рейтинг: 0 / 0
Триггер или многотабличное ограничение?
    #35020842
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
набросок межтабличного чека (пока не доведенный до ума...):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
--Межтабличное ограничение: нельзя заказать материал в количестве, превышающем остаток
CREATE ASSERTION zayavka_ne_mojet_bit_bolshe_ostatka
AS CHECK (
(SELECT SUM(info.Materials.MaterialValue) AS [Объем остатка] 
FROM info.Materials, info.Works, info.Parts, building.ZvMaterials, building.ZvRecMaterials
WHERE	info.Materials.WorkID=info.Works.WorkID 
		AND info.Works.partID=info.Parts.partID 
		AND info.Parts.estimateID=building.ZvMaterials.estimateID
		AND building.ZvMaterials.zvMaterialID=building.ZvMaterials.zvMaterialID
)
<=(...)
)
...
Рейтинг: 0 / 0
Триггер или многотабличное ограничение?
    #35020844
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iSestrinCREATE ASSERTION - это в какой субд вы почерпнули?
SQL-92
...
Рейтинг: 0 / 0
Триггер или многотабличное ограничение?
    #35021235
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вы уж простите, Compositum, но написано коряво до безобразия. Ощущение, что это курсовая работа из разряда "сдать и забыть".
...
Рейтинг: 0 / 0
Триггер или многотабличное ограничение?
    #35022041
Deniel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
если уж вы пользуетесь MS SQL Server, то рекомендую написать пользовательскую процедуру, реализующее и процесс добавления заявки и процесс проверки на допустимое количество...
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Триггер или многотабличное ограничение?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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