Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
fantanol Member Откуда: Сообщений: 191 |
Здравствуйте. Мне необходимо сделать запрос,который будет каждый раз заносить в ячейку "цена" рассчитанные значения которые нужно прописать в триггере. У меня есть ряд и сеанс. У сеанса есть 3 категории,рядов у нас 20. Для каждого сеанса свой процент,который будет умножен на "стоимость" из таблицы "фильм". Допустим,утренний 10%,дневной 15%,вечерний 18%. С рядами такая же схема. 1-5-ряды 10% 6-10 8% 11-15 7% 16-20 5%. Надеюсь на вашу помощь. Проще говоря. Когда выбираю ряд и сеанс,у меня в стоимости выводится подсчитанная сумма. Вот часть кода что удалось составить: create trigger raz for insert as begin declare @a int set a@ = (select код_билета from inserted) declare @b int set @b = (select код_фильма from inserted) declare @c int set @c = (select стоимость from Фильм where код_фильма = @b) if (@d="1") then update Билет set цена = @c*(0,9) update Билет set цена = @c*(1,1) end Схема таблиц,для полного понимания задачи К сообщению приложен файл. Размер - 23Kb |
7 дек 16, 15:23 [19976747] Ответить | Цитировать Сообщить модератору |
Владислав Колосов Member Откуда: Сообщений: 8317 |
fantanol, почему триггер, а не процедура? Данные выносите вызовом параметризованной процедуры, а не прямым обращением к таблице. |
7 дек 16, 15:42 [19976860] Ответить | Цитировать Сообщить модератору |
Sybex Member Откуда: Moscow Сообщений: 117 |
Когда пишется триггер - всегда нужно предусматривать работу не с одной строкой, а с множеством. |
7 дек 16, 15:51 [19976909] Ответить | Цитировать Сообщить модератору |
Sybex Member Откуда: Moscow Сообщений: 117 |
Вообще я согласен, что запихивать вычисление цены билета в триггер - это не самая здравая мысль и лучше это делать процедурой, хотя бы потому, что в этом случае будет всего лишь одна вставка, а с триггером это сначала insert, потом update. Ну, либо нужно делать INSTEAD OF триггер. Но для данного подхода, должно быть что-то на подобии: ;WITH CTE AS ( SELECT inserted.код_билета ,Фильм.стоимость * CASE WHEN inserted.ряд <= 5 THEN 1.1 WHEN inserted.ряд <= 10 THEN 1.08 WHEN inserted.ряд <= 15 THEN 1.07 ELSE 1.05 END * CASE inserted.код_сеанса WHEN 1 THEN 1.1 --утренний WHEN 2 THEN 1.15 --дневной ELSE THEN 1.18 --вечерний END AS [цена] FROM inserted JOIN Фильм ON Фильм.код_фильма = inserted.код_фильма ) UPDATE Билет SET цена = CTE.цена FROM Билет JOIN CTE ON Билет.код_билета = CTE.код_билета; |
7 дек 16, 16:42 [19977141] Ответить | Цитировать Сообщить модератору |
fantanol Member Откуда: Сообщений: 191 |
я так понимаю,это полная процедура? я вообще навязываюсь на триггер,просто мне предложили такой вариант. вот и получился такой код если не допустят,то придется делать триггер(( |
||
7 дек 16, 18:48 [19977742] Ответить | Цитировать Сообщить модератору |
fantanol Member Откуда: Сообщений: 191 |
что с ним не так?create procedure Цена WITH CTE as begin ( SELECT inserted.код_билета ,Фильм.стоимость * CASE WHEN inserted.ряд <= 5 THEN 1.1 WHEN inserted.ряд <= 10 THEN 1.08 WHEN inserted.ряд <= 15 THEN 1.07 ELSE 1.05 END * CASE inserted.код_сеанса WHEN 1 THEN 1.1 --утренний WHEN 2 THEN 1.15 --дневной ELSE THEN 1.18 --вечерний END AS [цена] FROM inserted JOIN Фильм ON Фильм.код_фильма = inserted.код_фильма ) UPDATE Билет SET цена = CTE.цена FROM Билет JOIN CTE ON Билет.код_билета = CTE.код_билета; end |
8 дек 16, 16:43 [19981307] Ответить | Цитировать Сообщить модератору |
londinium Member Откуда: Киев Сообщений: 1193 |
fantanol, все с ним не так. таблица INSERTED используется ТОЛЬКО в триггерах |
8 дек 16, 17:10 [19981436] Ответить | Цитировать Сообщить модератору |
fantanol Member Откуда: Сообщений: 191 |
можете пожалуйста помочь,сделать триггер? |
||
8 дек 16, 17:16 [19981469] Ответить | Цитировать Сообщить модератору |
buven Member Откуда: Сообщений: 792 |
А что будете делать, когда включится система лояльности для постоянных клиентов с фиксированной скидкой 10% на все сеансы? Судя по схеме придется заводить по экземпляру каждого билета на каждый сеанс. и потом при покупке умудриться не продать билет на то же место человеку, который не участвует в программе лояльности... С ума сойдешь так...
Выводится - ключевое слово. Про процедуру вам говорили видимо в том плане, что цену нужно на лету рассчитывать и отдавать в форнт, а не рассчитывать и хранить. А после покупки фиксировать ту цену, по которой продали со ссылкой на код билета в другой сущности. Я ничего не перепутал? |
||||
8 дек 16, 17:45 [19981587] Ответить | Цитировать Сообщить модератору |
Владислав Колосов Member Откуда: Сообщений: 8317 |
buven, э-э бизнес-логику не программируют на триггерах в сиквеле. Может где-то и пишут, но не здесь. Если нужны какие-то предварительные вычисления с сохранением результата в таблицах, то используют процедуры. В данном случае проблему получения корректной информации о билете моно решить не прибегая к вычислениям при сохранении записи о билете, т.к. у билета есть характеристики, которые позволяют вычислить его стоимость запросом. Например. Билет: зал, кресло, время. Фильм: зал, время, базовая цена Скидка: категория, время, величина скидки |
8 дек 16, 17:57 [19981625] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
Если у вас триггерофобия, это не значит что она у всего остального мира... |
||
8 дек 16, 18:08 [19981654] Ответить | Цитировать Сообщить модератору |
buven Member Откуда: Сообщений: 792 |
Не придерживаюсь какой то одной стороны, однако было бы интересно узнать реальный пример на триггерах в вашей практике. Если вдруг найдется время - не сочтите за труд. На моем веку просто триггеры использовались максимум для создания события, по которому дальше уже шла бизнес обработка, когда о результате одного БП нужно было оповестить соседний. Никакой записи результатов расчетов при этом в триггере не производилось. |
||||
8 дек 16, 18:32 [19981741] Ответить | Цитировать Сообщить модератору |
fantanol Member Откуда: Сообщений: 191 |
у меня нет постоянных клиентов и скидок для них. у меня есть "стоимость" в таблице фильм. которую нужно каждый раз умножать на "сеанс" и "ряд" из таблицы "билет"для вывода этих расчетов в "цену" |
||
8 дек 16, 18:47 [19981784] Ответить | Цитировать Сообщить модератору |
buven Member Откуда: Сообщений: 792 |
Дык вам его написали вот тут 19977141 уже. Хотя судя по коду первого триггера и процедуры - вы не знаете, инструкцию CREATE TRIGGER... Тут в комментариях пример с CTE на Instead of update. Вам чуть докрутить и выйдет ваш триггер. Но если уж полезли в эти дебри - придется почитать про триггеры, их типы, какой когда срабатывает и иже с ними... Работы - непочатый край. А все потому, что не хотите править своего же клиента. Когда сдавать курсовую Помощь с программой ? В разделе "Работа" ходит человек который может вам ее написать и дорассказать то, что забылось с лекций. |
||||
8 дек 16, 19:47 [19981975] Ответить | Цитировать Сообщить модератору |
fantanol Member Откуда: Сообщений: 191 |
Есть есть время до сдачи. И платить за этот код уже нет смысла,ведь часть есть. Ладно если бы у меня вообще программы не было. А так осталось лишь его доделать и всё) сомневаюсь что правильно написал use 123 go create trigger TR on T inserted OF UPDATE AS WITH CTE AS ( SELECT inserted.код_билета ,Фильм.стоимость * CASE WHEN inserted.ряд <= 5 THEN 1.1 WHEN inserted.ряд <= 10 THEN 1.08 WHEN inserted.ряд <= 15 THEN 1.07 ELSE 1.05 END * CASE inserted.код_сеанса WHEN 1 THEN 1.1 --утренний WHEN 2 THEN 1.15 --дневной ELSE THEN 1.18 --вечерний END AS [цена] FROM inserted JOIN Фильм ON Фильм.код_фильма = inserted.код_фильма ) UPDATE Билет SET цена = CTE.цена FROM Билет JOIN CTE ON Билет.код_билета = CTE.код_билета; update Билет go |
||
8 дек 16, 20:44 [19982108] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
Вообще, триггеры изначально и задумывались как средство реализации бизнес-логики на стороне сервера БД. |
||||
8 дек 16, 22:25 [19982399] Ответить | Цитировать Сообщить модератору |
Sybex Member Откуда: Moscow Сообщений: 117 |
И правильно сомневаетесь. Я говорил о триггере "INSTEAD OF", а не "INSERTED OF". Ох, я так понимаю это всё учебные примеры?! Так что разжую и в рот положу. Очень упрощённо! Для таблиц есть два типа триггеров обычные, которые выполняются после операции, и INSTED OF, которые выполняются вместо операции. Т.е. если вы используете первый тип триггера, то сервер сначала выполнит операцию вставки/обновления/удаления записей в таблице, а потом начнёт выполнять код триггера. А если используется второй тип, то код триггера выполняется вместо самой операции вставки/обновления/удаления и в таком случае вам нужно всё это сделать самому в коде триггера. Если используете первый тип, то триггер будет выглядеть так:
А если второго типа, то так:
А вообще вместо всех этих триггеров лучше использовать для вставки и обновления данных хранимые процедуры, но у Вас там вроде уже какой-то клиентский код есть, так что это просто в справочных целях на будущее:
|
|||||
12 дек 16, 14:56 [19993681] Ответить | Цитировать Сообщить модератору |
fantanol Member Откуда: Сообщений: 191 |
Ну как примеры) Курсовые такие Спасибо за расписанные и подробные примеры Только мне сейчас еще один понадобился. И на этот раз уже без примера буду. У меня есть дата продажи,просмотра,бронирования и возврата. Как в триггере можно реализовать запрет на ввод после определенной даты? Допустим нельзя вводить дату продажи выше чем дата просмотра. Дату бронирования выше возврата. Запрет на бронирование за несколько часов до просмотра. Вообще с этими данными можно составить кучу запретов. Но мне хотя бы пример как сделать описанные выше,дальше сам буду стараться.(Находятся они в одной таблице) Буду благодарен. |
||
14 дек 16, 18:39 [20004019] Ответить | Цитировать Сообщить модератору |
buven Member Откуда: Сообщений: 792 |
Хватит мучить базу. Тяните на форму, где у вас кнопка "Бронировать", дату начала сеанса, сравнивайте ее с текущей, и если нужно - блокируйте кнопку, чтобы мусорные данные даже не попытались попасть в базу. |
||||
14 дек 16, 19:39 [20004184] Ответить | Цитировать Сообщить модератору |
fantanol Member Откуда: Сообщений: 191 |
у меня задача это всё через триггер сделать( |
||||
14 дек 16, 19:59 [20004230] Ответить | Цитировать Сообщить модератору |
Sybex Member Откуда: Moscow Сообщений: 117 |
Именно через триггер? Не просто "средствами СУБД", а именно "через триггер"? Просто для таких задач (когда данные расположены в одной таблице) используют не триггеры, а ограничения CHECK, которые вешаются на таблицу. Но если в Вас такие условия, то посмотрите по форуму, тут уже всплывали похожие задачи. Например, Триггер на проверку |
||||
15 дек 16, 11:12 [20006034] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6801 |
fantanol, instead of trigger, в нём проверка |
15 дек 16, 11:16 [20006062] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |