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

Откуда:
Сообщений: 6
Здравствуйте! Необходимо создать триггер, который бы проверял значение поля в связной таблице и уже на основании этого значения проверял запись при вставке. Существует 2 таблицы: Информация о абитуриенте и Зачисленные абитуриенты (студенты), в зависимости от того поступает ли абитуриента от предприятия (по контракту) следует исключить возможность вставки записи в таблицу Зачисленные абитуриенты с типом "Бюджет".
Собственно сам триггер:
ALTER TRIGGER [dbo].[T_tblPersonResult_ChkYesID]
ON [dbo].[tblPersonResult]
FOR INSERT,UPDATE
AS
SET NOCOUNT ON
declare @m1 bit
SELECT MoneyPerson=@m1 FROM tblPerson,tblPersonResult WHERE tblPerson.PersonID=tblPersonResult.PersonID
if(@m1=1)
BEGIN
SELECT COUNT(*) FROM inserted, tblPersonResult WHERE inserted.TypeID=1
BEGIN
RAISERROR ('Нельзя зачислить абитуриента на бюджет, т.к. у абитуриента есть договор с предприятием',16,1)
ROLLBACK TRANSACTION
END
end
Подскажите что не так. Спасибо.
1 ноя 15, 08:55    [18354959]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
Serg_77m
Member

Откуда: Донецк
Сообщений: 237
Papadzyan
Подскажите что не так. Спасибо.
Всё не так :)
ALTER TRIGGER [dbo].[T_tblPersonResult_ChkYesID] 
   ON  [dbo].[tblPersonResult] 
   FOR INSERT,UPDATE
AS 
SET NOCOUNT ON
declare @m1 bit

SELECT MoneyPerson=@m1 FROM tblPerson,tblPersonResult WHERE tblPerson.PersonID=tblPersonResult.PersonID
/*
Этот запрос просто выберет столько NULL'ов, сколько записей в tblPersonResult.
Во-первых, здесь должна участвовать таблица Inserted, иначе запрос будет проверять
всю таблицу tblPersonResult на каждое обновление или вставку данных.
Во-вторых, если хочется значение поля MoneyPerson присвоить переменой @m1, 
надо писать наоборот: @m1=MoneyPerson
А в третьих, лучше вообще обойтись без этой переменной.
Вставка или обновление может затрагивать сразу несколько записей,
которые все надо проверить, а в переменной будет значение только одной из них.
*/

if(@m1=1)
    BEGIN
	SELECT COUNT(*) FROM inserted, tblPersonResult WHERE inserted.TypeID=1
        -- Это я так понимаю, отладка? Одна из таблиц здесь лишняя.

    BEGIN
        RAISERROR ('Нельзя зачислить абитуриента на бюджет, т.к. у абитуриента есть договор с предприятием',16,1)
		ROLLBACK TRANSACTION
    END
 end


Если я правильно понял назначение полей, должно быть примерно так:
ALTER TRIGGER [dbo].[T_tblPersonResult_ChkYesID] 
   ON  [dbo].[tblPersonResult] 
   FOR INSERT,UPDATE
AS 
SET NOCOUNT ON -- а нужно ли это здесь?
if exists(
  SELECT *
  FROM tblPerson,inserted
  WHERE tblPerson.PersonID=inserted.PersonID
    and inserted.TypeID=1
    and MoneyPerson=1
)
BEGIN
    RAISERROR ('Нельзя зачислить абитуриента на бюджет, т.к. у абитуриента есть договор с предприятием',16,1)
    ROLLBACK TRANSACTION
END
1 ноя 15, 12:06    [18355154]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
aleks2
Guest
Я с вас тащусь. Один неуч круче другого.

-- да уж... бред сивой кобылы.
-- реформа высшего образования просит свои плоды

ALTER TRIGGER [dbo].[T_tblPersonResult_ChkYesID] 
 ON [dbo].[tblPersonResult] 
 FOR INSERT,UPDATE
AS 
  if exists(SELECT * FROM inserted as i inner join tblPerson as p on i.PersonID = p.PersonID WHERE i.TypeID = 1 and p.MoneyPerson = 1 )
    RAISERROR ('Нельзя зачислить абитуриента на бюджет, т.к. у абитуриента есть договор с предприятием',16,1);

-- учись студент.
1 ноя 15, 12:12    [18355171]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
Serg_77m
Member

Откуда: Донецк
Сообщений: 237
aleks2
Я с вас тащусь. Один неуч круче другого.
Я знаю, что можно написать join. Я подстроился под стиль оригинала.
1 ноя 15, 12:18    [18355183]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
Papadzyan
Member

Откуда:
Сообщений: 6
Я только начал изучать SQL не судите строго) Я действительно думал что нужно отдельным селектом выбрать данные и присвоить переменной, а потом этой переменно манипулировать) Всем спасибо за помощь, буду изучать.
1 ноя 15, 12:20    [18355191]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
aleks2
Guest
Serg_77m
aleks2
Я с вас тащусь. Один неуч круче другого.
Я знаю, что можно написать join. Я подстроился под стиль оригинала.

Ну дык, осознай и бессмысленносnь ROLLBACK в триггере.
1 ноя 15, 12:22    [18355196]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
Serg_77m
Member

Откуда: Донецк
Сообщений: 237
aleks2
Ну дык, осознай и бессмысленносnь ROLLBACK в триггере.
???
use tempdb
go
create table dbo.tblPerson (PersonID int primary key,Name varchar(30),MoneyPerson bit)
create table dbo.tblPersonResult (ID int identity primary key,PersonID int,TypeID int)
go
CREATE TRIGGER [dbo].[T_tblPersonResult_ChkYesID] 
 ON [dbo].[tblPersonResult] 
 FOR INSERT,UPDATE
AS 
  if exists(SELECT * FROM inserted as i inner join tblPerson as p on i.PersonID = p.PersonID WHERE i.TypeID = 1 and p.MoneyPerson = 1 )
    RAISERROR ('Нельзя зачислить абитуриента на бюджет, т.к. у абитуриента есть договор с предприятием',16,1);
go
insert into tblPerson (PersonID,Name,MoneyPerson) values (1,'Петя',0)
insert into tblPerson (PersonID,Name,MoneyPerson) values (2,'Вася',1)
go
insert into tblPersonResult (PersonID,TypeID) values (1,1)
-- ОК
go
insert into tblPersonResult (PersonID,TypeID) values (2,1)
-- Ошибка
go
select * from tblPersonResult
-- Но последняя запись добавилась

IDPersonIDTypeID
111
221


Моя очередь говорить: "Учись, студент"? :)
1 ноя 15, 12:39    [18355218]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
Rankatan
Guest
THROW 50000, 'Нельзя зачислить абитуриента на бюджет, т.к. у абитуриента есть договор с предприятием', 0; 


В этом случае произойдет автоматический откат
1 ноя 15, 16:01    [18355569]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить