Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите с написанием процедуры  [new]
Amesitia
Member

Откуда:
Сообщений: 5
Такое задание: Вы разрабатываете базу данных для информационной системы коммерческого предприятия (далее КП), обслуживающего товарищества собственников жилья и жил. кооперативы. КП координирует услуги электриков, сантехников, лифтеров, телефонистов - домофонщиков и т.д., то есть обслуживает насущные нужды домов, не контролируемых государственными органами ЖКХ.
Создана база данных с такими таблицами.

+
--------Здания----------
create table Building(
id int identity(1,1) primary key,
type1 char(5) check (type1 in ('tech', 'zhil')),
adress varchar(50)
)

drop table Building

--------Персонал--------
create table Staff(
id int identity(1,1) primary key,
name char(20) check (name like '[A-Z]%'),
type1 char(10) check (type1 in ('elec','santeh','lift','gas'))
)

drop table Staff

-----Здание-Персонал----
create table BSt(
id_b int references Building(id),
id_s int references Staff(id)
)

drop table BSt

--------Сервис----------
create table Serv(
id int identity(1,1) primary key,
func char(15) check (func in ('elec','santeh','lift','gas')),
class char(10) check (class in ('elec','santeh','lift','gas'))
)

drop table Serv

-----Здание-Сервис------
create table BServ(
id_b int references Building(id),
id_s int references Serv(id)
)

drop table BServ

--------Задания---------
create table Task(
id int identity(1,1) primary key,
def char(70),
id_r int references Room(id),
id_serv int references Serv(id),
start datetime,
finish datetime,
id_staff int references Staff(id),
status1 varchar(6) check (status1 in ('made', 'run', 'expect', 'cancel'))
)

drop table Task


Нужно написать процедуру, проверяющую наличие ситуации, когда сотруднику А, обслуживающему здание1, дано в исполнение задание В, привязанное к зданию 2. И наоборот. Если квалификация сотрудников позволяет им поменяться заданиями, переназначить задания. Проверка и переназначение должны быть произведены только для невыполненных и не просроченных заданий.
Помогите, пожалуйста! Голову уже капитально клинит.(
13 фев 14, 19:22    [15564682]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
alex564657498765453
Member

Откуда:
Сообщений: 1925
Так а на каком моменте клинит?
13 фев 14, 19:32    [15564722]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
Amesitia
Member

Откуда:
Сообщений: 5
Уже на начальном. Я просто не знаю, с какой стороны к ней подойти.(
13 фев 14, 19:33    [15564730]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104760
Amesitia
Я просто не знаю, с какой стороны к ней подойти

напишите сначала просто запросы, которые будут выполняться
13 фев 14, 21:26    [15565026]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
Amesitia
Member

Откуда:
Сообщений: 5
create proc Checking as
begin
	declare @id1 int, @id2 int, @id_b1 int, @id_b2 int, @build1 int, @build2 int, @serv1 int, @serv2 int, @status1 varchar(6), @status2 varchar(6)
	declare @rb1 table(id_b int)
	declare @rb2 table(id_b int)
	declare cursor1 cursor for select id_staff from All_inf
	open cursor1
	fetch cursor1 into @id1

	while (@@fetch_status = 0) begin
		set @build1 = (select id_b from All_inf where id_staff = @id1)
		set @status1 = (select status1 from All_inf where id_staff = @id1)
		set @serv1 = (select id_serv from Staff where id = @id1)
		insert @rb1 select id_b from BSt where id_s = @id1
				
		declare cursor2 cursor for select id_staff from All_inf
		open cursor2
		fetch cursor2 into @id2
		while (@@fetch_status = 0) begin
			set @id_b1 = (select count(*) from @rb1 where id_b = @build1)
			set @status2 = (select status1 from All_inf where id_staff = @id1)
			if (@status1 = 'made' or @status1 = 'cancel' or @status2 = 'made' or @status2 = 'cancel' or @id_b1 = 1) begin
				fetch cursor1 into @id2
				truncate @rb1
				set @id1 = @id2
				set @build1 = (select id_b from All_inf where id_staff = @id1)
				set @status1 = (select status1 from All_inf where id_staff = @id1)
				set @serv1 = (select id_serv from Staff where id = @id1)
				insert @rb1 select id_b from BSt where id_s = @id1
			end
			else begin
				set @build2 = (select id_b from All_inf where id_staff = @id2)
				set @serv2 = (select id_serv from Staff where id = @id2)
				insert @rb2 select id_b from BSt where id_s = @id2
				set @id_b1 = (select count(*) from @rb1 where id_b = @build2)
				set @id_b2 = (select count(*) from @rb2 where id_b = @build1)
				if (@id_b1 = 1 and @id_b2 = 1 and @serv2 = @serv1) begin
					update Task set id_staff = @id1 where id_staff = @id2 and id_b = @build2
					update Task set id_staff = @id2 where id_staff = @id1 and id_b = @build1
				end
				else fetch cursor2 into @id2
			end
		end	
		close cursor2
		deallocate cursor2
		fetch cursor1 into @id1
	end
	close cursor1
	deallocate cursor1
end


Пока получилось как-то так. Общая мысль такая - двумя курсорами пробегаться по таблице, проверяя для каждых двух записей, могут ли они поменяться. Правда, возникла проблема с очисткой таблицы @rb1 (truncate @rb1). С чем это может быть связано? Создавалась переменная как таблица...
14 фев 14, 00:27    [15565496]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31435
Amesitia
возникла проблема с очисткой таблицы @rb1 (truncate @rb1). С чем это может быть связано?
truncate нельзя делать для таблиц-переменных, только delete

А вообще код ужасен.
Сотни тысяч запросов вместо одного-двух-трёх.
14 фев 14, 00:36    [15565515]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
Amesitia
Member

Откуда:
Сообщений: 5
alexeyvg
Amesitia
возникла проблема с очисткой таблицы @rb1 (truncate @rb1). С чем это может быть связано?
truncate нельзя делать для таблиц-переменных, только delete

А вообще код ужасен.
Сотни тысяч запросов вместо одного-двух-трёх.


И как с ним работать, если нужно очистить всю таблицу?
Понимаю, что он громоздкий, но я не знаю, как его усовершенствовать. И так мозг плавится.
14 фев 14, 00:39    [15565519]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31435
Amesitia
И как с ним работать, если нужно очистить всю таблицу?
С чем, с delete?

delete имятаблицы
14 фев 14, 00:48    [15565534]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
Amesitia
Member

Откуда:
Сообщений: 5
alexeyvg, поняла уже.
И все равно осталась проблема с оптимизацией. Вы сможете как-то помочь?
14 фев 14, 00:50    [15565541]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Amesitia,

готов помочь платно.
14 фев 14, 08:32    [15565926]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
Азагаш
Member

Откуда:
Сообщений: 450
Amesitia,
а что? долго выполняется? или совсем не работает как надо?
14 фев 14, 08:53    [15565982]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с написанием процедуры  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31435
Amesitia
И все равно осталась проблема с оптимизацией. Вы сможете как-то помочь?
Скорее, это не оптимизация, а написание процедуры как последовательность реляционных преобразований данных, как и положено в СУБД, вместо действий циклами и скалярными переменными.

Я готов помочь так же, как и остальные - подсказать и поправить ошибки.

Не пишите сразу процедуру, пишите, как сказал Glory, отдельные стейтменты.

Составьте максимально формальное описание того, что вам нужно сделать с данными, составьте как бы алгоритм.
Например:
1. сотруднику А, обслуживающему здание1, дано в исполнение задание В, привязанное к зданию 2
2. ....

Потом каждый пункт напишите как один запрос, просто выборку данных, удовлетворяющих указанным условиям.

А потом уже, когда напишите и будете всё это понимать, легко переделаете эти запросы как проверки или обновления данных и оформите как процедуру.
14 фев 14, 09:25    [15566065]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить