Bulk: Einheit 1-3
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user