Bulk: Einheit 1-3

This commit is contained in:
2026-03-17 20:25:47 +01:00
parent 49d6f914ff
commit e897ffe9d9
3 changed files with 388 additions and 50 deletions

View File

@@ -0,0 +1,205 @@
-- ####################################################
-- # STORED PROCEDURES #
-- ####################################################
-- Stored Procedure: sp_MieteFahrzeug
CREATE OR ALTER PROCEDURE sp_MieteFahrzeug
@KundeID BIGINT,
@FahrzeugID BIGINT,
@Start DATE,
@Ende DATE
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @VerfuegbareFahrzeuge INT;
BEGIN TRY
BEGIN TRANSACTION;
-- Prüfe, ob Kunde existiert
IF NOT EXISTS (SELECT 1 FROM Customer WHERE id = @KundeID)
BEGIN
RAISERROR('Kunde mit der angegebenen ID existiert nicht.', 16, 1);
END;
-- Prüfe, ob Fahrzeug existiert
IF NOT EXISTS (SELECT 1 FROM Vehicle WHERE id = @FahrzeugID)
BEGIN
RAISERROR('Fahrzeug mit der angegebenen ID existiert nicht.', 16, 1);
END;
-- Prüfe, ob Enddatum nach Startdatum liegt
IF @Ende <= @Start
BEGIN
RAISERROR('Das Enddatum muss nach dem Startdatum liegen.', 16, 1);
END;
-- Prüfe Verfügbarkeit des Fahrzeugs
SELECT @VerfuegbareFahrzeuge = COUNT(*)
FROM Rental
WHERE vehicleID = @FahrzeugID
-- Ein Fahrzeug ist besetzt, wenn der neue Zeitraum sich mit einem bestehenden überschneidet
-- und noch nicht zurückgegeben wurde (actualEnd IS NULL)
AND actualEnd IS NULL
AND (
(@Start < rentalEnd)
AND (@Ende > rentalStart)
);
IF @VerfuegbareFahrzeuge > 0
BEGIN
RAISERROR('Das Fahrzeug ist im angegebenen Zeitraum nicht verfügbar.', 16, 1);
END;
-- Erstelle den Mietdatensatz
-- Hinweis: actualEnd ist initial NULL
INSERT INTO Rental (customerID, vehicleID, rentalStart, rentalEnd, actualEnd)
VALUES (@KundeID, @FahrzeugID, @Start, @Ende, NULL);
DECLARE @MietID BIGINT = SCOPE_IDENTITY();
COMMIT TRANSACTION;
-- Rückgabewert
SELECT
@MietID AS id,
'Mietvertrag erfolgreich erstellt.' AS message,
@Start AS rentalStart,
@Ende AS rentalEnd;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
DECLARE @ErrMssp_MieteFahrzeug NVARCHAR(4000) = ERROR_MESSAGE();
RAISERROR(@ErrMssp_MieteFahrzeug, 16, 1);
END CATCH;
END;
GO
-- Stored Procedure: sp_RueckgabeFahrzeug
-- Aktualisiert actualEnd und berechnet Endpreis via UDF
-- Stored Procedure: sp_RueckgabeFahrzeug
-- Aktualisiert actualEnd und berechnet Endpreis via UDF
CREATE OR ALTER PROCEDURE sp_RueckgabeFahrzeug
@MietID BIGINT,
@RueckgabeDatum DATETIME
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @Tagespreis DECIMAL(10, 2);
DECLARE @StartDatum DATE;
DECLARE @Endpreis DECIMAL(10, 2);
BEGIN TRY
BEGIN TRANSACTION;
-- Prüfe, ob Miet-ID existiert
IF NOT EXISTS (SELECT 1 FROM Rental WHERE id = @MietID)
BEGIN
RAISERROR('Mietvertrag mit der angegebenen ID existiert nicht.', 16, 1);
END;
-- Hole Start-Datum und Tagespreis (aus VehicleCategory via Vehicle)
SELECT
@StartDatum = r.rentalStart,
@Tagespreis = vc.pricePerDay
FROM Rental r
JOIN Vehicle v ON r.vehicleID = v.id
JOIN VehicleCategory vc ON v.vehicleCategoryID = vc.id
WHERE r.id = @MietID;
-- Berechne den Endpreis mit Hilfe der UDF aus Einheit 2
SET @Endpreis = dbo.fn_BerechneMietkosten(@StartDatum, @RueckgabeDatum, @Tagespreis);
-- Prüfe, ob Rückgabedatum nach Startdatum liegt
IF @RueckgabeDatum < @StartDatum
BEGIN
RAISERROR('Das Rückgabedatum kann nicht vor dem Mietstart liegen.', 16, 1);
END;
-- Aktualisiere den Rental-Datensatz (actualEnd)
UPDATE Rental
SET
actualEnd = @RueckgabeDatum
WHERE id = @MietID;
COMMIT TRANSACTION;
-- Rückgabewert
SELECT
@MietID AS id,
'Fahrzeug erfolgreich zurückgegeben.' AS message,
@RueckgabeDatum AS actualEnd,
@Endpreis AS calculatedTotalPrice;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
DECLARE @ErrMssp_RueckgabeFahrzeug NVARCHAR(4000) = ERROR_MESSAGE();
RAISERROR(@ErrMssp_RueckgabeFahrzeug, 16, 1);
END CATCH;
END;
GO
-- =====================================================
-- TRIGGER
-- =====================================================
-- Hinweis: Die Status-Update Trigger wurden entfernt, da die Tabelle 'Vehicle'
-- laut Schema keine 'status' Spalte besitzt. Die Verfügbarkeit wird
-- dynamisch über Views (v_VerfuegbareFahrzeuge) ermittelt.
-- Archive table for Customer (if not exists)
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='CustomerArchiv' AND xtype='U')
BEGIN
CREATE TABLE CustomerArchiv (
id BIGINT NOT NULL,
name VARCHAR(50) NOT NULL,
Adress VARCHAR(100) NOT NULL,
driverlicenseid VARCHAR(100) NOT NULL,
deletedDate DATETIME NOT NULL,
PRIMARY KEY (id, deletedDate)
);
END;
GO
-- Trigger: trg_Archivierung
-- Kopiert gelöschte Kunden in KundenArchiv-Tabelle statt physisch zu löschen
CREATE OR ALTER TRIGGER trg_Archivierung
ON Customer
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION;
-- Kopiere gelöschte Kunden in die Archiv-Tabelle
INSERT INTO CustomerArchiv (id, name, Adress, driverlicenseid, deletedDate)
SELECT
id,
name,
Adress,
driverlicenseid,
GETDATE()
FROM deleted;
-- Lösche den Datensatz nur, wenn die Archivierung erfolgreich war
DELETE FROM Customer
WHERE id IN (SELECT id FROM deleted);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
DECLARE @ErrMsstrg_Archivierung NVARCHAR(4000) = ERROR_MESSAGE();
RAISERROR(@ErrMsstrg_Archivierung, 16, 1);
END CATCH;
END;
GO