Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.11.2014, 15:15   #1
Prizrak86
Форумчанин
 
Аватар для Prizrak86
 
Регистрация: 15.10.2011
Сообщений: 139
По умолчанию Триггер, неправильно выполняется условие

Есть таблица

в ней по [код_статуса_брони] остаются те помещения, которые заняты в текущий момент (код 1 и 2).

запрос для этого
Код:
SELECT *
FROM [dbo].[Бронирование_помещения] as бронь
Where (бронь.Код_статуса_брони = 1 or бронь.Код_статуса_брони = 2)
результат запроса


пишу триггер событие добавление записи
Код:
create trigger ProverkaSvobodnNomerov_12
on [dbo].[Бронирование_помещения]
for insert
as

 if (
	(SELECT 
		COUNT(*) 
	FROM 
		[dbo].[Бронирование_помещения] as бронь, 
		inserted
	WHere 
		(бронь.Код_статуса_брони = 1 or бронь.Код_статуса_брони = 2) and 
		бронь.Код_помещения = inserted.Код_помещения) > 0) 
Begin
	RAISERROR ('номер уже занят другим гостем', 16, 10)
end
при этом я сравниваю [Код_помещения] и вывожу количество записей в условие, логика такова, если будут записи в результате этого запроса, значит это помещение забронировано и тогда выводиться сообщение, но на деле это сообщение выводится всегда, что не так?
Программист это не профессия, программист - это образ жизни.
Prizrak86 вне форума Ответить с цитированием
Старый 19.11.2014, 15:39   #2
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Логика такова, что этот запрос
Цитата:
Сообщение от Prizrak86 Посмотреть сообщение
Код:
SELECT 
		COUNT(*) 
	FROM 
		[dbo].[Бронирование_помещения] as бронь, 
		inserted
	WHere 
		(бронь.Код_статуса_брони = 1 or бронь.Код_статуса_брони = 2) and 
		бронь.Код_помещения = inserted.Код_помещения
всегда будет возвращать больше 0. Почему? Читайте о том, что из себя представляет таблица inserted.
Создайте хранимую процедуру для добавления и в ней, перед тем как непосредственно добавить запись, выполняйте проверку. Либо используйте триггеры instead of.

Последний раз редактировалось Streletz; 19.11.2014 в 15:49.
Streletz вне форума Ответить с цитированием
Старый 19.11.2014, 16:20   #3
Prizrak86
Форумчанин
 
Аватар для Prizrak86
 
Регистрация: 15.10.2011
Сообщений: 139
По умолчанию

Спасибо. Я понял почему она выдает результат больше нуля. Но как получить запись которая добавляется?

Цитата:
Сообщение от Streletz Посмотреть сообщение
Логика такова, что этот запрос
всегда будет возвращать больше 0. Почему? Читайте о том, что из себя представляет таблица inserted.
Создайте хранимую процедуру для добавления и в ней, перед тем как непосредственно добавить запись, выполняйте проверку. Либо используйте триггеры instead of.
Цитата из статьи на которую вы мне указали.

Цитата:
В таблице inserted находятся копии строк, с которыми работали инструкции INSERT или UPDATE. При выполнении транзакции вставки или обновления происходит одновременное добавление строк в таблицу триггера и в таблицу inserted.Строки таблицы inserted являются копиями новых строк таблицы триггера.
Прочитал Ваши ссылки, здесь написано что в таблице inserted содержаться добавляемые строки, а по ходу работы получается что в ней содержится вся копия таблицы. Так что в ней содержится и как мне получить ту единственную запись, которая будет добавлена в таблицу???
Программист это не профессия, программист - это образ жизни.

Последний раз редактировалось Stilet; 19.11.2014 в 17:17.
Prizrak86 вне форума Ответить с цитированием
Старый 19.11.2014, 17:54   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Там не копия, а временная таблица именно с добавляемыми записями. И триггер отрабатывает после вставки. Т.е. вставляемые записи уже есть в таблице и их нужно исключить во WHERE. И отката транзакции в упор не вижу. Да, и наверно лучше триггер instead of
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 19.11.2014, 18:31   #5
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Как-то плоховато у Вас с теорией, автор.
Да и с проектированием.

Вот что такое по логике проверка свободных номеров - это выдача инфы ресепшенисту или заезжающему о количестве и ассортименте доступных для съёма номеров. При чём тут проверка _вставки_ ?

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

Если же писать код, то лучше писать ХП, а не триггер, триггеры вообще редко стоит применять, ибо они легко могут давать сложности. А про триггеры конечно ещё почитать стоит.

Ну и общего плана замечания - имхо,некрасиво, что в базе поля на русском.
Ну и COUNT(*) - плохая практика, указывайте одно какое-то поле, обычно первичный ключ, т.к. * не всегда сервер разрулит это в оптимизацию, думаю.
phomm вне форума Ответить с цитированием
Старый 19.11.2014, 19:14   #6
Prizrak86
Форумчанин
 
Аватар для Prizrak86
 
Регистрация: 15.10.2011
Сообщений: 139
По умолчанию

Цитата:
Сообщение от phomm Посмотреть сообщение
Как-то плоховато у Вас с теорией, автор.
Да и с проектированием.

Вот что такое по логике проверка свободных номеров - это выдача инфы ресепшенисту или заезжающему о количестве и ассортименте доступных для съёма номеров. При чём тут проверка _вставки_ ?

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

Если же писать код, то лучше писать ХП, а не триггер, триггеры вообще редко стоит применять, ибо они легко могут давать сложности. А про триггеры конечно ещё почитать стоит.

Ну и общего плана замечания - имхо,некрасиво, что в базе поля на русском.
Ну и COUNT(*) - плохая практика, указывайте одно какое-то поле, обычно первичный ключ, т.к. * не всегда сервер разрулит это в оптимизацию, думаю.
Спасибо за конструктивную критику. Я поговорю об этом с преподавателем.
Программист это не профессия, программист - это образ жизни.
Prizrak86 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не выполняется условие Nich. C# (си шарп) 0 27.11.2013 18:10
$.ajax не выполняется условие Mixasnt JavaScript, Ajax 24 11.11.2013 23:42
Не выполняется условие Astash Помощь студентам 2 03.12.2011 11:21
Не выполняется условие Ragnarek45 Общие вопросы Delphi 3 10.12.2010 15:08
не выполняется условие Link12 Общие вопросы C/C++ 6 30.03.2010 19:36