Федеральное агентство по образованию
Государственное образовательное учреждение высшего профессионального образования
Новгородский Государственный Университет имени Ярослава Мудрого
Кафедра Информационных технологий и систем
Отчет по лабораторной работе №4
«Использование триггеров»
по дисциплине
«Базы Данных»
Выполнил:
Студент группы 9092
Шалакин Николай Николаевич
«___»__________2012 г.
Проверила:
___________ ___Петрова С.Ю.
«___»________________2012 г.
2012 г.
Упражнение 1.
Триггер в системе бухгалтерского учета. Проверяет сумму транзакций на положительность, предотвращая вставку или изменение столбцов транзакций, приводящие к отрицательному балансу.
CREATE SCHEMA Accounting
CREATE TABLE Accounting.Account
(
AccountNumber CHAR(10)
CONSTRAINT PKAccount PRIMARY KEY
)
CREATE TABLE Accounting.AccountActivity
(
AccountNumber CHAR(10)
CONSTRAINT Accounting_AccountActivity
FOREIGN KEY REFERENCES Accounting.Account(AccountNumber),
TransactionNumber CHAR(20),
Date DATETIME,
TransactionAmount MONEY,
CONSTRAINT PRAccountActivity
PRIMARY KEY (AccountNumber, TransactionNumber)
)
----------------------------------------------------------------------------------
CREATE TRIGGER Accounting.AccountActivity$insertTrigger
ON Accounting.AccountActivity
AFTER INSERT, UPDATE AS
BEGIN
DECLARE @rowsAffected INT,
@msg VARCHAR(2000)
SET @rowsAffected = @@rowcount
IF @rowsAffected = 0 RETURN
SET NOCOUNT ON
SET ROWCOUNT 0
BEGIN TRY
IF EXISTS (SELECT AccountNumber
FROM Accounting.AccountActivity AS AccountActivity
WHERE EXISTS (SELECT *
FROM inserted
WHERE inserted.AccountNumber = AccountActivity.AccountNumber)
GROUP BY AccountNumber
HAVING SUM(TransactionAmount) < 0)
BEGIN
IF @rowsAffected = 1
SELECT @msg = 'Account: ' + AccountNumber +
'TransactionNumber: '+
CAST(TransactionNumber AS VARCHAR(36)) +
' for amount: ' + CAST(TransactionAmount AS VARCHAR(10))+
'cannot be processed as it will cause a negative balance'
FROM inserted
ELSE
SELECT @msg='One of the rows caused a negative balance'
RAISERROR (@msg, 16, 1)
END
END TRY
BEGIN CATCH
if @@trancount >0
ROLLBACK TRANSACTION
DECLARE @ERROR_MESSAGE VARCHAR(4000)
SET @ERROR_MESSAGE = ERROR_MESSAGE()
RAISERROR(@ERROR_MESSAGE,16,1)
END CATCH
END
----------------------------------------------------------------------------------
SELECT sys.trigger_events.type_desc
FROM sys.trigger_events
JOIN sys.triggers
on sys.triggers.object_id = sys.trigger_events.object_id
where sys.triggers.name = 'AccountActivity$insertTrigger'
Результат:
type_desc |
INSERT |
UPDATE |
INSERT INTO Accounting.Account(AccountNumber) VALUES('1111111111')
INSERT INTO Accounting.Account(AccountNumber) VALUES('2222222222')
INSERT INTO Accounting.AccountActivity(AccountNumber,TransactionNumber,Date,TransactionAmount)
VALUES ('1111111111','A0001','20050712',100)
INSERT INTO Accounting.AccountActivity(AccountNumber,TransactionNumber,Date,TransactionAmount)
VALUES ('1111111111','A0002','20050713',100)
INSERT INTO
Результат:
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
Accounting.AccountActivity(AccountNumber,TransactionNumber,Date,TransactionAmount)
VALUES ('1111111111','A0003','20050714',-300)
Результат:
Msg 50000, Level 16, State 1, Procedure AccountActivity$insertTrigger, Line 37
Account: 1111111111 TransactionNumber: A0003 for amount: -300.00 cannot be processed as it will cause a negative balance
Msg 3609, Level 16, State 1, Line 10
The transaction ended in the trigger. The batch has been aborted.
INSERT INTO Accounting.AccountActivity(AccountNumber,TransactionNumber,Date,TransactionAmount)
SELECT '1111111111','A0004','20050714',100
UNION
SELECT '2222222222','A0005','20050715',100
UNION
SELECT '2222222222','A0006','20050715',100
UNION
SELECT '2222222222','A0007','20050715',-201
Результат:
Msg 50000, Level 16, State 1, Procedure AccountActivity$insertTrigger, Line 37
One of the rows caused a negative balance
Msg 3609, Level 16, State 1, Line 3
The transaction ended in the trigger. The batch has been aborted.
Упражнение 2.
Триггеры в комбинации с применением флажков условий. Триггер контролирует наличие не более одного флага по умолчанию, равного 1.
CREATE SCHEMA Internet
GO
CREATE TABLE Internet.Url
(
UrlId INT NOT NULL IDENTITY(1,1)
CONSTRAINT PKUrl PRIMARY KEY,
Name VARCHAR(60) NOT NULL CONSTRAINT AKUrl_Name UNIQUE,
Url VARCHAR(200) NOT NULL CONSTRAINT AKUrlJJrl UNIQUE
)
CREATE TABLE Internet.UrlStatusType
(
UrlStatusTypeId INT NOT NULL
CONSTRAINT PRUrlStatusType PRIMARY KEY,
Name VARCHAR(20) NOT NULL CONSTRAINT AKUrlStatusType UNIQUE,
DefaultFlag BIT NOT NULL,
DisplayOnSiteFlag BIT NOT NULL)
CREATE TABLE Internet.UrlStatus
(
UrlStatusId INT NOT NULL IDENTITY(1,1)
CONSTRAINT PKUrlStatus PRIMARY KEY,
UrlStatusTypeId INT NOT NULL
CONSTRAINT Internet_UrlStatType$def_stat_type_of$Internet_UrlStat
REFERENCES Internet.UrlStatusType(UrlStatusTypeId),
UrlId INT NOT NULL
CONSTRAINT internet_Url$has_status_history_in$internet_UrlStatus
REFERENCES Internet.Url(UrlId),
ActiveDate DATETIME,
CONSTRAINT AKUrlStatus_statusUrlDate
UNIQUE (UrlStatusTypeId, UrlId, ActiveDate))
----------------------------------------------------------------------------------
INSERT Internet.UrlStatusType (UrlStatusTypeId, Name, DefaultFlag, DisplayOnSiteFlag)
SELECT 1, 'Unverifid', 1,0
Union
SELECT 2,'Verified',0,1
UNION
SELECT 3,'Unable to locate',0,0
SELECT * FROM Internet.UrlStatusType
Результат:
UrlStatusTypeId |
Name |
DefaultFlag |
DisplayOnSiteFlag |
1 |
Unverifid |
1 |
0 |
2 |
Verified |
0 |
1 |
3 |
Unable to locate |
0 |
0 |
CREATE TRIGGER Internet.Url$afterInsert
ON InterNet.Url
AFTER INSERT AS
BEGIN
DECLARE @rowsAffected INT,
@msg VARCHAR(2000)
SET @rowsAffected = @@rowcount
IF @rowsAffected = 0 RETURN
SET NOCOUNT ON
SET ROWCOUNT 0
BEGIN TRY
INSERT INTO Internet.UrlStatus(UrlId, UrlStatusTypeId,ActiveDate)
SELECT INSERTED.UrlId, UrlStatusType.UrlStatusTypeId, current_timestamp
FROM INSERTED
CROSS JOIN (SELECT UrlStatusTypeId
FROM UrlStatusType
WHERE DefaultFlag = 1) AS UrlStatusType
END TRY
BEGIN CATCH
IF @@trancount>0
ROLLBACK TRANSACTION
DECLARE @ERROR_MESSAGE varchar(4000)
SET @ERROR_MESSAGE = ERROR_MESSAGE()
RAISERROR (@ERROR_MESSAGE,16,1)
END CATCH
END
----------------------------------------------------------------------------------
INSERT into Internet.Url(Name, Url)
VALUES ('More info can be found here', 'http://spaces.msn.com/members/drsql')
SELECT * FROM Internet.Url
SELECT * FROM Internet.UrlStatus
Результат:
UrlId |
Name |
Url |
1 |
More info can be found here |
http://spaces.msn.com/members/drsql |
UrlStatusId |
UrlStatusTypeId |
UrlId |
ActiveDate |
1 |
1 |
1 |
2012-03-30 10:16:09.383 |