Sunteți pe pagina 1din 10

Ministerul Educaţiei, Culturii şi Cercetarii al Republicii Moldova

Universitatea Tehnică a Moldovei

Facultatea Calculatoare, Informatică şi Microelectronică

Departamentul Ingineria Software si Automatica

RAPORT
Lucrare de laborator nr.3
Disciplina: Baze de date
Tema: Proceduri stocate și funcții definite de utilizator. Crearea și
utilizarea declanșatoarelor.

A efectuat: Caraman Eliza

A verificat: asis.univ. G.Cebotari

Chişinău 2024
Primele 5 exerciții pagina 329:

CREATE PROCEDURE CalculeazaNumarProfesoriFacultate


AS
BEGIN
SET NOCOUNT ON; -- Evitarea raportării numărului de rânduri afectate

-- Declarați variabila pentru a stoca numărul de profesori


DECLARE @NumarProfesori INT;

-- Calcularea numărului total de profesori


SELECT @NumarProfesori = COUNT(*)
FROM [universitatea].[dbo].[profesori];

-- Returnarea rezultatului
SELECT @NumarProfesori AS NumarTotalProfesori;
END;

EXEC CalculeazaNumarProfesoriFacultate;

Result:

CREATE PROCEDURE NumarStundetiFaraEvaluare


@NumarStundetiFaraEvaluare INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;

SELECT @NumarStundetiFaraEvaluare = COUNT(DISTINCT sr.Id_Student)


FROM [universitatea].[dbo].[studenti_reusita] sr
LEFT JOIN [universitatea].[dbo].[studenti] s ON sr.Id_Student = s.Id_Student
WHERE sr.Nota < 5 OR sr.Nota IS NULL;

END;

DECLARE @NumarStundetiFaraEvaluare INT;


EXEC NumarStundetiFaraEvaluare @NumarStundetiFaraEvaluare OUTPUT;
SELECT @NumarStundetiFaraEvaluare AS 'NumarStundetiFaraEvaluare';

Result:
CREATE PROCEDURE ProfesoriCuMaiMulteDiscipline
@numar_discipline INT
AS
BEGIN
SELECT
p.Nume_Profesor,
p.Prenume_Profesor
FROM
[universitatea].[dbo].[profesori] p
INNER JOIN
[universitatea].[dbo].[studenti_reusita] sr ON p.Id_Profesor = sr.Id_Profesor
GROUP BY
p.Nume_Profesor, p.Prenume_Profesor
HAVING
COUNT(DISTINCT sr.Id_Disciplina) >= @numar_discipline
END

DECLARE @numar_discipline_input INT


SET @numar_discipline_input = 3 -- poți înlocui această valoare cu numărul dorit de
discipline

-- Apelarea procedurii stocate cu parametrul specificat


EXEC ProfesoriCuMaiMulteDiscipline @numar_discipline = @numar_discipline_input

Result:

CREATE PROCEDURE NumarExameneStudent


@NumeStudent NVARCHAR(100),
@NumarExamene INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;

-- Declarați variabila locală pentru a stoca ID-ul studentului


DECLARE @IdStudent INT

-- Găsiți ID-ul studentului bazat pe numele dat


SELECT @IdStudent = Id_Student
FROM studenti
WHERE Nume_Student = @NumeStudent

-- Calculați numărul de examene la care s-a prezentat studentul


SELECT @NumarExamene = COUNT(*)
FROM studenti_reusita
WHERE Id_Student = @IdStudent

-- Afișați rezultatul
SELECT @NumarExamene AS 'Numar_Examene'
END

DECLARE @NumarExameneStudent INT

-- Apelați procedura stocată cu numele studentului dorit


EXEC NumarExameneStudent 'Brasovianu', @NumarExamene = @NumarExameneStudent OUTPUT

-- Afișați rezultatul
PRINT 'Numărul de examene la care s-a prezentat studentul: ' +
CAST(@NumarExameneStudent AS NVARCHAR(10))

Result:

CREATE OR ALTER PROCEDURE [dbo].[InserareStudentSiReusita]


@Id_Student INT,
@Nume_Student VARCHAR(50),
@Prenume_Student VARCHAR(50),
@Data_Nastere_Student DATE,
@Adresa_Postala_Student VARCHAR(500),
@Cod_Grupa CHAR(6)
AS
BEGIN
SET NOCOUNT ON;

-- Inserarea informatiilor studentului in tabelul 'studenti'


INSERT INTO [dbo].[studenti] (Id_Student, Nume_Student, Prenume_Student,
Data_Nastere_Student, Adresa_Postala_Student)
VALUES (@Id_Student, @Nume_Student, @Prenume_Student, @Data_Nastere_Student,
@Adresa_Postala_Student);

DECLARE @Id_Grupa SMALLINT;


SELECT @Id_Grupa = Id_Grupa FROM [dbo].[grupe] WHERE Cod_Grupa = @Cod_Grupa;

IF @Id_Grupa IS NOT NULL


BEGIN
-- Presupunând că fiecare disciplină are cel puțin un profesor asociat,
selectăm un profesor pentru fiecare disciplină
-- Aceasta este o simplificare; în practică, logica de selecție a profesorilor
poate fi mai complexă
INSERT INTO [dbo].[studenti_reusita] (Id_Student, Id_Disciplina, Id_Profesor,
Id_Grupa, Tip_Evaluare, Nota)
SELECT DISTINCT @Id_Student, d.Id_Disciplina, (SELECT TOP 1 p.Id_Profesor FROM
[dbo].[profesori] p ORDER BY NEWID()), @Id_Grupa, 'Examen', NULL
FROM [dbo].[discipline] d
WHERE NOT EXISTS (
SELECT 1 FROM [dbo].[studenti_reusita]
WHERE Id_Student = @Id_Student AND Id_Disciplina = d.Id_Disciplina
);
END
ELSE
BEGIN
-- Oferă un mesaj de eroare dacă codul grupei nu există
RAISERROR ('Codul grupei specificat nu există în baza de date.', 16, 1);
END
END;
GO

EXEC [dbo].[InserareStudentSiReusita]
@Id_Student = 30,
@Nume_Student = 'Caraman',
@Prenume_Student = 'Eliza',
@Data_Nastere_Student = '2001-01-15',
@Adresa_Postala_Student = 'Str. Calea Iesilor 45',
@Cod_Grupa = 'TI171';

SELECT * FROM [dbo].[studenti] WHERE Id_Student = 30;

Result:

Primele 5 exerciții pagina 344:

-- Verificăm dacă declanșatorul există deja și, în caz afirmativ, îl ștergem


IF OBJECT_ID ('dbo.trVerificaModificareNoteData', 'TR') IS NOT NULL
DROP TRIGGER dbo.trVerificaModificareNoteData;
GO

-- Crearea declanșatorului
CREATE TRIGGER dbo.trVerificaModificareNoteData
ON dbo.studenti_reusita
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;

-- Verificăm dacă coloanele 'Nota' și 'Data_Evaluare' au fost modificate


IF UPDATE(Nota) OR UPDATE(Data_Evaluare)
BEGIN
-- Aici se poate adăuga orice logică dorită, de exemplu, înregistrarea
modificărilor, trimiterea unei notificări etc.
PRINT 'Coloanele Nota sau Data_Evaluare au fost modificate.';
END
END;
GO

-- Actualizăm nota și data evaluării pentru un student specific și o disciplină


specifică
UPDATE dbo.studenti_reusita
SET Nota = 9, -- Presupunând că modificăm nota
Data_Evaluare = '2024-03-01' -- Și data evaluării
WHERE Id_Student = 30;

Result:

-- Verificăm dacă declanșatorul există deja și, în caz afirmativ, îl ștergem


IF OBJECT_ID ('tr_inregistrare_noua', 'TR') IS NOT NULL
DROP TRIGGER tr_inregistrare_noua;
GO

-- Crearea declanșatorului modificat


CREATE TRIGGER tr_inregistrare_noua
ON orarul
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;

-- Verificăm dacă coloana 'Auditoriu' a fost actualizată


IF UPDATE(Auditoriu)
BEGIN
-- Trecem prin fiecare înregistrare actualizată
SELECT
'Disciplina: ' + CAST(d.Id_Disciplina AS VARCHAR) +
', Ora: ' + CAST(i.Ora AS VARCHAR) +
', Grupa: ' + CAST(g.Cod_Grupa AS VARCHAR) +
', Zi: ' + i.Zi +
', Bloc: ' + 'N/A' + -- Presupunem că nu avem informații despre bloc în
acest tabel
', Auditoriu vechi: ' + CAST(d.Auditoriu AS VARCHAR) +
', Auditoriu nou: ' + CAST(i.Auditoriu AS VARCHAR) AS MesajInformare
FROM inserted i
INNER JOIN deleted d ON i.Id_Grupa = d.Id_Grupa AND i.Zi = d.Zi AND i.Ora =
d.Ora
INNER JOIN grupe g ON i.Id_Grupa = g.Id_Grupa
WHERE d.Auditoriu <> i.Auditoriu;
END
END;
GO

Result:

-- Verificăm dacă declanșatorul există deja și, în caz afirmativ, îl ștergem


IF OBJECT_ID ('tr_AutoPopulateStudentiReusita', 'TR') IS NOT NULL
DROP TRIGGER tr_AutoPopulateStudentiReusita;
GO

-- Crearea declanșatorului
CREATE TRIGGER tr_AutoPopulateStudentiReusita
ON studenti
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;

-- Pentru fiecare student nou inserat, generăm intrările corespunzătoare în


studenti_reusita
INSERT INTO studenti_reusita(Id_Student, Id_Disciplina, Id_Profesor, Id_Grupa,
Tip_Evaluare, Nota, Data_Evaluare)
SELECT
i.Id_Student,
d.Id_Disciplina,
p.Id_Profesor,
g.Id_Grupa,
'Examen', -- Sau alt tip de evaluare, dacă este necesar
NULL, -- Nota este necunoscută la momentul inserării
NULL -- Data evaluării este necunoscută
FROM
inserted i
CROSS JOIN discipline d
CROSS JOIN profesori p
CROSS JOIN grupe g
-- Filtrarea poate fi necesară pentru a asigura validitatea combinațiilor de
Id_Disciplina, Id_Profesor, și Id_Grupa
END;
GO

Result:

-- Verificăm dacă declanșatorul există deja și, în caz afirmativ, îl ștergem


IF OBJECT_ID ('tr_InterziceModificareaNotelorData', 'TR') IS NOT NULL
DROP TRIGGER tr_InterziceModificareaNotelorData;
GO

-- Crearea declanșatorului
CREATE TRIGGER tr_InterziceModificareaNotelorData
ON studenti_reusita
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;

-- Verificăm dacă update-ul afectează studenții din grupa „CIB171”


IF EXISTS (
SELECT 1
FROM inserted i
INNER JOIN deleted d ON i.Id_Student = d.Id_Student AND i.Id_Disciplina =
d.Id_Disciplina AND i.Id_Profesor = d.Id_Profesor AND i.Id_Grupa = d.Id_Grupa AND
i.Tip_Evaluare = d.Tip_Evaluare
INNER JOIN grupe g ON i.Id_Grupa = g.Id_Grupa
WHERE g.Cod_Grupa = 'CIB171'
AND (i.Nota < d.Nota OR (i.Data_Evaluare != d.Data_Evaluare AND
d.Data_Evaluare IS NOT NULL))
)
BEGIN
-- Afișăm un mesaj de avertizare și anulăm tranzacția
RAISERROR ('Modificarea notelor sau a datei evaluării este interzisă pentru
grupa CIB171.', 16, 1);
ROLLBACK TRANSACTION;
END
END;
GO

Result:
-- Verificăm dacă declanșatorul DDL există deja și, în caz afirmativ, îl ștergem
IF EXISTS (SELECT * FROM sys.triggers WHERE name =
'tr_InterziceModificareId_Disciplina')
BEGIN
DROP TRIGGER tr_InterziceModificareId_Disciplina ON DATABASE;
END
GO

-- Crearea declanșatorului DDL


CREATE TRIGGER tr_InterziceModificareId_Disciplina
ON DATABASE
FOR ALTER_TABLE
AS
BEGIN
SET NOCOUNT ON;

-- Extragem informații despre evenimentul DDL care a declanșat acest trigger


DECLARE @EventData XML = EVENTDATA();
DECLARE @SchemaName NVARCHAR(256) = @EventData.value('(/EVENT_INSTANCE/SchemaName)
[1]', 'NVARCHAR(256)');
DECLARE @TableName NVARCHAR(256) = @EventData.value('(/EVENT_INSTANCE/ObjectName)
[1]', 'NVARCHAR(256)');
DECLARE @AlterCommand NVARCHAR(MAX) =
@EventData.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]', 'NVARCHAR(MAX)');

-- Verificăm dacă comanda de modificare implică coloana 'Id_Disciplina'


IF CHARINDEX('Id_Disciplina', @AlterCommand) > 0
BEGIN
RAISERROR ('Modificarea coloanei Id_Disciplina este interzisă în baza de date
universitatea.', 16, 1);
ROLLBACK;
END
END;
GO

Result:
Concluzie:

În concluzie , exercițiile prezentate demonstrează utilizarea și implementarea procedurilor


stocate și a declanșatoarelor în baza de date SQL Server. Acestea sunt instrumente esențiale
în gestionarea și monitorizarea datelor într-un mediu de bază de date relațional.

Procedurile stocate oferă o modalitate de a defini și executa logică complexă direct în baza de
date. Ele pot fi folosite pentru diverse scopuri, inclusiv calcularea și returnarea rezultatelor,
manipularea datelor și implementarea logicii de afaceri personalizate. În plus, ele pot fi
reutilizate și apelate din diferite aplicații sau scripturi, ceea ce duce la o dezvoltare și
întreținere mai eficiente a aplicațiilor.

Declanșatoarele sunt obiecte care răspund automat la anumite evenimente în baza de date,
cum ar fi inserările, actualizările sau ștergerile de date. Ele permit implementarea de logică
automatizată, de exemplu, validarea datelor înainte de a fi introduse în baza de date sau
notificarea despre anumite evenimente către alte componente ale sistemului. Prin utilizarea
lor, se poate asigura consistența și integritatea datelor în baza de date.

În contextul managementului bazelor de date, aceste instrumente sunt esențiale pentru


implementarea și menținerea unui sistem robust și scalabil. Ele permit dezvoltatorilor și
administratorilor să controleze și să monitorizeze comportamentul bazei de date într-un mod
flexibil și eficient.

În concluzie, cunoașterea și utilizarea procedurilor stocate și a declanșatoarelor sunt aspecte


esențiale ale dezvoltării și administrării bazelor de date în SQL Server, contribuind la
securitatea, performanța și fiabilitatea sistemului.

S-ar putea să vă placă și