Działanie triggera prośba o pomoc

0

Witam, zwracam się o pomoc w stworzeniu tiggera z użyciem funkcji lub widoku. Stworzyłam funckję, która ma mi zliczać sumę wszystkich pasażerów na statku (załoga + reszta) i chcę do tego stworzyć trigger, że przy wpisywaniu nowego rekordu ma on sprawdzać czy dozwolona ilość miejsc nie została przekroczona. Próbowałam i na funkcji, i na widoku i nic mi nie wychodzi, cały czas dodaje mi rekord mimo przekroczonej liczby dozwolonej. Nie mam pojęcia już jak to zrobić, bo robiłam na wiele sposobów

-funkcja

CREATE FUNCTION [dbo].[SumaPasażerów] (@Idp int)
RETURNS int
AS
BEGIN
DECLARE @rb int
SELECT @rb=Ilość_załogi+Ilość_pasażerów from pasażerowie where id=@Idp
RETURN @rb
END

  • trigger na widoku z użyciem funkcji

CREATE TRIGGER dbo.KontrolaPasażerów ON dbo.ilośćosóbnastatku
instead of INSERT AS
DECLARE @ww int, @idp int
SELECT @ww=[Ilość miejsc pasażerskich] from dbo.IlośćOsóbNaStatku
IF @ww > @idp
Begin
PRINT 'DOZWOLONA ILOŚĆ OSÓB'
end
ELSE
BEGIN
PRINT 'ZAGROŻENIE! ZA DUŻO PASAŻERÓW!'
ROLLBACK
END

0

Może wzrok mnie myli, ale ja tu nie widzę użycia funkcji w triggerze. Za to widzę, nie zainicjowaną zmienną @idp typu int, której wartość równa się null,w związku z tym IF @ww > @idp też NULL. Poza tym jeśli chcesz zrobić rollback, musi to być w jednej transakcji, która się zaczyna od BEGIN TRAN.

0

Może dlatego ci nie wychodzi, że w trigerrze do zmiennej @idp nie podstawiasz wartości z funkcji. I wtedy @www jest zawsze od niej większa.

0

Jeśli jest to funkcja skalarna:

IF (SELECT  [dbo].[SumaPasażerów] (@Idp) ) < @ww
BEGIN
PRINT 'DOZWOLONA ILOŚĆ OSÓB'
END.....
0

A może by tak tradycyjnie

raiseerror ('Nie można dodać, bo ... nie', 1, 2) with seterror 

zamiast tego ROLLBACK

 A Rollback w kodzie - tam gdzie masz insert, tam wyłapujesz błąd.
0
CREATE FUNCTION [dbo].[SumaPasażerów] (@Idp int)
RETURNS int
AS
BEGIN
DECLARE @rb int
SELECT @rb=Ilość_załogi+Ilość_pasażerów from pasażerowie where id=@Idp /*rozumiem, że ID to ID_Statku*/
RETURN @rb
END

-- trigger na widoku z użyciem funkcji

CREATE TRIGGER dbo.KontrolaPasażerów 
ON dbo.ilośćosóbnastatku
instead of INSERT 
AS
DECLARE @ww int, @idp int
begin
SELECT top 1 @ww=[Ilość miejsc pasażerskich], @idp=[ID Statku] from inserted
IF @ww>(select [dbo].[SumaPasażerów] (@Idp))
begin
raiserror('ZAGROŻENIE! ZA DUŻO PASAŻERÓW!', 1, 16)
rollback
end
END
0

Nie wiem jak wygląda Twoja baza, ale stworzyłem sobie przykładową jak poniżej i bez problemu działa (trigger założyłem na tabelę, a nie widok)

/*struktura*/
create table statek (
id_statku int identity,
nazwa varchar(20))
go
create table pasazerowie (
id_statku int not null,
ilosc_zalogi int not null,
ilosc_pasazerow int not null)
go
create table kursy (
id_kursu int identity,
id_statku int not null,
ilosc_osob int not null,
data_wyplyniecia datetime not null,
data_powrotu datetime not null)
go
create function sumapasazerow (@idp int)
returns int
as
begin
declare @rb int
select @rb=ilosc_zalogi+ilosc_pasazerow from pasazerowie where id_statku=@idp
return @rb
end
go
create trigger kontrolapasazerow 
on kursy
for insert 
as
declare @ww int, @idp int
begin
select top 1 @ww=ilosc_osob, @idp=id_statku from inserted
if @ww>(select dbo.sumapasazerow(@idp))
begin
raiserror('zagrożenie! za dużo pasażerów!', 1, 16)
rollback
end
end
go

/*dane*/
insert into statek (nazwa) values ('anna'), ('maria');
insert into pasazerowie (id_statku, ilosc_zalogi, ilosc_pasazerow) values (1, 5, 100), (2, 7, 120);

/*test*/
--insert into kursy (id_statku, ilosc_osob, data_wyplyniecia, data_powrotu) select 1, 95, getdate(), getdate()+1; --dodaje
--insert into kursy (id_statku, ilosc_osob, data_wyplyniecia, data_powrotu) select 1, 130, getdate()+1, getdate()+3; --odrzuca
--insert into kursy (id_statku, ilosc_osob, data_wyplyniecia, data_powrotu) select 2, 195, getdate()+1, getdate()+2; --odrzuca
--insert into kursy (id_statku, ilosc_osob, data_wyplyniecia, data_powrotu) select 2, 127, getdate()+2, getdate()+4; --dodaje

1 użytkowników online, w tym zalogowanych: 0, gości: 1