Bulk: Einheit 1-3
This commit is contained in:
@@ -3,71 +3,67 @@ GO
|
||||
USE "2025_5bhitn_konstantin_hintermayer_smarter_rentDB";
|
||||
GO
|
||||
|
||||
DROP TABLE IF EXISTS Rental;
|
||||
|
||||
CREATE TABLE Customer
|
||||
(
|
||||
id BIGINT NOT NULL IDENTITY(1,1),
|
||||
name VARCHAR(50) NOT NULL,
|
||||
Adress VARCHAR(100) NOT NULL,
|
||||
driverlicenseid VARCHAR(100) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
DROP TABLE IF EXISTS Customer;
|
||||
|
||||
DROP TABLE IF EXISTS [Location];
|
||||
|
||||
DROP TABLE IF EXISTS Vehicle;
|
||||
|
||||
DROP TABLE IF EXISTS VehicleCategory;
|
||||
|
||||
CREATE TABLE Customer (
|
||||
id BIGINT NOT NULL IDENTITY (1, 1),
|
||||
[name] VARCHAR(50) NOT NULL,
|
||||
Adress VARCHAR(100) NOT NULL,
|
||||
driverlicenseid VARCHAR(100) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE Location
|
||||
(
|
||||
id BIGINT NOT NULL IDENTITY(1,1),
|
||||
name VARCHAR NOT NULL,
|
||||
address VARCHAR NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
CREATE TABLE Location (
|
||||
id BIGINT NOT NULL IDENTITY (1, 1),
|
||||
[name] VARCHAR(250) NOT NULL,
|
||||
[address] VARCHAR(250) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE Rental
|
||||
(
|
||||
id BIGINT NOT NULL IDENTITY(1,1),
|
||||
rentalStart DATETIME NOT NULL,
|
||||
rentalEnd DATETIME NOT NULL,
|
||||
actualEnd DATETIME NOT NULL,
|
||||
customerID BIGINT NOT NULL,
|
||||
vehicleID BIGINT NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
CREATE TABLE Rental (
|
||||
id BIGINT NOT NULL IDENTITY (1, 1),
|
||||
rentalStart DATETIME NOT NULL,
|
||||
rentalEnd DATETIME NOT NULL,
|
||||
actualEnd DATETIME NULL,
|
||||
customerID BIGINT NOT NULL,
|
||||
vehicleID BIGINT NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE Vehicle
|
||||
(
|
||||
id BIGINT NOT NULL IDENTITY(1,1),
|
||||
brand VARCHAR(50) NOT NULL,
|
||||
model VARCHAR(50) NOT NULL,
|
||||
licensePlate VARCHAR(8) NOT NULL,
|
||||
buyDate DATE NOT NULL,
|
||||
locationID BIGINT NOT NULL,
|
||||
vehicleCategoryID BIGINT NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
CREATE TABLE Vehicle (
|
||||
id BIGINT NOT NULL IDENTITY (1, 1),
|
||||
brand VARCHAR(50) NOT NULL,
|
||||
model VARCHAR(50) NOT NULL,
|
||||
licensePlate VARCHAR(8) NOT NULL,
|
||||
buyDate DATE NOT NULL,
|
||||
locationID BIGINT NOT NULL,
|
||||
vehicleCategoryID BIGINT NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE VehicleCategory
|
||||
(
|
||||
id BIGINT NOT NULL IDENTITY(1,1),
|
||||
description Varchar NOT NULL,
|
||||
pricePerDay DECIMAL NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
CREATE TABLE VehicleCategory (
|
||||
id BIGINT NOT NULL IDENTITY (1, 1),
|
||||
[description] VARCHAR(250) NOT NULL,
|
||||
pricePerDay DECIMAL NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
ALTER TABLE Rental
|
||||
ADD CONSTRAINT FK_Customer_TO_Rental
|
||||
FOREIGN KEY (customerID)
|
||||
REFERENCES Customer (id);
|
||||
ADD CONSTRAINT FK_Customer_TO_Rental FOREIGN KEY (customerID) REFERENCES Customer (id);
|
||||
|
||||
ALTER TABLE Rental
|
||||
ADD CONSTRAINT FK_Vehicle_TO_Rental
|
||||
FOREIGN KEY (vehicleID)
|
||||
REFERENCES Vehicle (id);
|
||||
ADD CONSTRAINT FK_Vehicle_TO_Rental FOREIGN KEY (vehicleID) REFERENCES Vehicle (id);
|
||||
|
||||
ALTER TABLE Vehicle
|
||||
ADD CONSTRAINT FK_Location_TO_Vehicle
|
||||
FOREIGN KEY (locationID)
|
||||
REFERENCES Location (id);
|
||||
ADD CONSTRAINT FK_Location_TO_Vehicle FOREIGN KEY (locationID) REFERENCES Location (id);
|
||||
|
||||
ALTER TABLE Vehicle
|
||||
ADD CONSTRAINT FK_VehicleCategory_TO_Vehicle
|
||||
FOREIGN KEY (vehicleCategoryID)
|
||||
REFERENCES VehicleCategory (id);
|
||||
ADD CONSTRAINT FK_VehicleCategory_TO_Vehicle FOREIGN KEY (vehicleCategoryID) REFERENCES VehicleCategory (id);
|
||||
137
Einheit_2/2025_5BHITN_Konstantin_Hintermayer_seed_database.sql
Normal file
137
Einheit_2/2025_5BHITN_Konstantin_Hintermayer_seed_database.sql
Normal file
@@ -0,0 +1,137 @@
|
||||
-- Insert test data into the Location table
|
||||
INSERT INTO [dbo].[Location] ([name], [address])
|
||||
VALUES
|
||||
('Downtown Office', '123 Main St, Cityville'),
|
||||
('Airport Terminal', '456 Airport Rd, Cityville'),
|
||||
('City Center', '789 Central Ave, Cityville'),
|
||||
('Suburban Outlet', '321 Suburb St, Cityville'),
|
||||
('Train Station', '654 Rail Rd, Cityville');
|
||||
|
||||
-- Insert test data into the VehicleCategory table
|
||||
INSERT INTO VehicleCategory ([description], [pricePerDay])
|
||||
VALUES
|
||||
('Compact Car', 29.99),
|
||||
('SUV', 49.99),
|
||||
('Luxury Sedan', 89.99),
|
||||
('Minivan', 59.99),
|
||||
('Pickup Truck', 69.99);
|
||||
|
||||
-- Insert test data into the Vehicle table
|
||||
INSERT INTO Vehicle (brand, model, licensePlate, buyDate, locationID, vehicleCategoryID)
|
||||
VALUES
|
||||
('Toyota', 'Corolla', 'ABC1234', '2020-06-15', 1, 1),
|
||||
('Honda', 'CR-V', 'XYZ5678', '2019-03-22', 2, 2),
|
||||
('BMW', '5 Series', 'LMN9012', '2021-01-10', 3, 3),
|
||||
('Ford', 'Transit', 'GHI3456', '2020-11-05', 4, 4),
|
||||
('Chevrolet', 'Silverado', 'JKL7890', '2018-07-19', 5, 5);
|
||||
|
||||
-- Insert test data into the Customer table
|
||||
INSERT INTO Customer (name, Adress, driverlicenseid)
|
||||
VALUES
|
||||
('John Doe', '1 Elm St, Cityville', 'D123456789'),
|
||||
('Jane Smith', '2 Oak St, Cityville', 'D987654321'),
|
||||
('Bob Johnson', '3 Pine St, Cityville', 'D456123789'),
|
||||
('Alice Williams', '4 Maple St, Cityville', 'D654789123'),
|
||||
('Charlie Brown', '5 Cedar St, Cityville', 'D321654987');
|
||||
|
||||
|
||||
GO
|
||||
-- ########################################################
|
||||
-- # Views #
|
||||
-- ########################################################
|
||||
-- View: v_VerfuegbareFahrzeuge
|
||||
-- Zeigt Fahrzeuge an, die nicht vermietet sind oder deren Rückgabedatum in der Vergangenheit liegt
|
||||
CREATE OR ALTER VIEW v_VerfuegbareFahrzeuge AS
|
||||
SELECT
|
||||
v.id,
|
||||
v.brand,
|
||||
v.model,
|
||||
v.licensePlate,
|
||||
vc.description AS category,
|
||||
vc.pricePerDay,
|
||||
l.name AS location,
|
||||
l.address AS locationAddress,
|
||||
CASE
|
||||
WHEN r.id IS NULL THEN 'Available'
|
||||
WHEN r.rentalEnd < CAST(GETDATE() AS DATE) THEN 'Available (Overdue Return)'
|
||||
ELSE 'Not Available'
|
||||
END AS status
|
||||
FROM Vehicle v
|
||||
JOIN VehicleCategory vc ON v.vehicleCategoryID = vc.id
|
||||
JOIN Location l ON v.locationID = l.id
|
||||
LEFT JOIN Rental r ON v.id = r.vehicleID AND r.actualEnd IS NULL
|
||||
WHERE r.id IS NULL OR r.actualEnd < CAST(GETDATE() AS DATE);
|
||||
GO
|
||||
-- View: v_UmsatzProKategorie
|
||||
-- Zeigt den kumulierten Umsatz pro Fahrzeugkategorie an
|
||||
CREATE OR ALTER VIEW v_UmsatzProKategorie AS
|
||||
SELECT
|
||||
vc.id,
|
||||
vc.description AS category,
|
||||
vc.pricePerDay,
|
||||
COUNT(r.id) AS totalRentals,
|
||||
SUM(
|
||||
DATEDIFF(DAY, r.rentalStart, COALESCE(r.rentalEnd, CAST(GETDATE() AS DATE)))
|
||||
* vc.pricePerDay
|
||||
) AS totalRevenue
|
||||
FROM VehicleCategory vc
|
||||
LEFT JOIN Vehicle v ON vc.id = v.vehicleCategoryID
|
||||
LEFT JOIN Rental r ON v.id = r.vehicleID
|
||||
GROUP BY
|
||||
vc.id,
|
||||
vc.description,
|
||||
vc.pricePerDay;
|
||||
GO
|
||||
|
||||
|
||||
-- ########################################################
|
||||
-- # User Defined Functions #
|
||||
-- ########################################################
|
||||
|
||||
-- Scalar Function: fn_BerechneMietkosten
|
||||
CREATE OR ALTER FUNCTION fn_BerechneMietkosten (
|
||||
@StartDatum DATE,
|
||||
@EndDatum DATE,
|
||||
@Tagespreis DECIMAL(10, 2)
|
||||
)
|
||||
RETURNS DECIMAL(10, 2)
|
||||
AS
|
||||
BEGIN
|
||||
DECLARE @AnzahlTage INT;
|
||||
DECLARE @Mietkosten DECIMAL(10, 2);
|
||||
|
||||
-- Berechne die Anzahl der Tage (mindestens 1 Tag)
|
||||
SET @AnzahlTage = DATEDIFF(DAY, @StartDatum, @EndDatum);
|
||||
|
||||
-- Falls das Enddatum vor oder gleich dem Startdatum ist, sind es mindestens 1 Tag
|
||||
IF @AnzahlTage < 1
|
||||
SET @AnzahlTage = 1;
|
||||
|
||||
-- Berechne die Gesamtkosten
|
||||
SET @Mietkosten = @AnzahlTage * @Tagespreis;
|
||||
|
||||
RETURN @Mietkosten;
|
||||
END;
|
||||
GO
|
||||
-- Table-Valued Function: fn_FahrzeugeAnStandort
|
||||
CREATE OR ALTER FUNCTION fn_FahrzeugeAnStandort (
|
||||
@StandortID INT
|
||||
)
|
||||
RETURNS TABLE
|
||||
AS
|
||||
RETURN (
|
||||
SELECT
|
||||
v.id,
|
||||
v.brand,
|
||||
v.model,
|
||||
v.licensePlate,
|
||||
v.buyDate,
|
||||
vc.description AS category,
|
||||
vc.pricePerDay,
|
||||
l.name AS locationName,
|
||||
l.address AS locationAddress
|
||||
FROM Vehicle v
|
||||
JOIN VehicleCategory vc ON v.vehicleCategoryID = vc.id
|
||||
JOIN Location l ON v.locationID = l.id
|
||||
WHERE v.locationID = @StandortID
|
||||
);
|
||||
@@ -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