summaryrefslogtreecommitdiff
path: root/task7_procedures.sql
blob: f3d7e8450d72570ef9f2fc7fbecb58d0a5ac464c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
----------------------
-- Первая процедура --
----------------------

CREATE PROCEDURE calculate_order_price
    @order_id INT,
    @price FLOAT OUTPUT
AS BEGIN
    SET @price = 0.0;

    DECLARE @delivery_id INT;
    SELECT @delivery_id=delivery_id FROM Shipments WHERE order_id=@order_id;
    IF @delivery_id IS NULL BEGIN
        RAISERROR (N'Доставка для данного заказа ещё не оформлена', 10, 1);
        RETURN;
    END

    DECLARE @gas_price FLOAT, @tonnage INT;
    SELECT @gas_price=gas_consumption / 100.0 * distance, @tonnage=tonnage
    FROM Deliveries
    JOIN Vehicles ON Deliveries.vehicle_id = Vehicles.id
    JOIN Routes ON Deliveries.route_id = Routes.id;

    DECLARE boxes_cursor CURSOR LOCAL
    FOR SELECT volume, weight, price wrap_price
        FROM Boxes JOIN Wrappings ON Boxes.wrapping_id = Wrappings.id
        WHERE order_id=@order_id
    OPEN boxes_cursor

    DECLARE @volume FLOAT, @weight FLOAT, @wrap_price INT;
    FETCH NEXT FROM boxes_cursor INTO @volume, @weight, @wrap_price;
    WHILE @@FETCH_STATUS=0 BEGIN
        SET @price = @price + @weight / CAST(@tonnage AS FLOAT) * @gas_price + @wrap_price;
        FETCH NEXT FROM boxes_cursor INTO @volume, @weight, @wrap_price;
    END
    SET @price = @price + 1000;
END
GO

DROP PROCEDURE calculate_order_price
GO

INSERT INTO Boxes (order_id, warehouse_id, wrapping_id, volume, weight)
VALUES (100022, 1, 1, 0.1, 10);

DECLARE @price INT;
EXEC calculate_order_price 100022, @price OUTPUT;
PRINT @price
GO

----------------------
-- Вторая процедура --
----------------------

CREATE PROCEDURE calculate_delivery_date
    @route_id INT,
    @order_date DATETIME,
    @delivery_date DATETIME OUTPUT
AS BEGIN
    DECLARE @distance FLOAT;
    SELECT @distance=distance FROM Routes WHERE id=@route_id;

    DECLARE @hours_driving FLOAT, @days_driving INT;
    -- Скорость перевозки 70 километров в час
    SET @hours_driving = @distance / 70.0;
    -- 8 часов сна на 12 часов езды
    SET @hours_driving = @hours_driving / 12.0 * 8.0;
    SET @days_driving = CAST(@hours_driving / 24.0 + 1 AS INT);

    -- Добавляем к дате заказа количество дней на поездку, один день
    -- на обработку посылки в терминале отправки и один в терминале
    -- приёма.
    SET @delivery_date = DATEADD(day, @days_driving + 2, @order_date);
END
GO

DROP PROCEDURE calculate_delivery_date
GO

DECLARE @order_date DATETIME, @delivery_date DATETIME;
SET @order_date = '2019-09-07';
EXEC calculate_delivery_date 1, @order_date, @delivery_date OUTPUT;
PRINT @delivery_date
GO

----------------------
-- Третья процедура --
----------------------

CREATE PROCEDURE calculate_discount_for_customer
    @customer_id INT
AS BEGIN
    DECLARE @money_spent INT;
    SELECT @money_spent=SUM(amount)
    FROM Payments JOIN Orders ON Payments.order_id = Orders.id
    WHERE customer_id=@customer_id;
    IF @money_spent IS NULL BEGIN
        RAISERROR (N'Данный клиент ещё не оплатил ни одного заказа', 10, 1);
        RETURN 0;
    END

    SET @money_spent = @money_spent - 10000;
    SET @money_spent = IIF(@money_spent < 0, 0, @money_spent);
    SET @money_spent = IIF(@money_spent > 40000, 40000, @money_spent);
    RETURN CAST(@money_spent / 40000 * 15 + 5 AS INT);
END
GO

DROP PROCEDURE calculate_discount_for_customer
GO

DECLARE @discount INT;
EXEC @discount = calculate_discount_for_customer 10;
PRINT @discount
GO

DECLARE @discount INT;
EXEC @discount = calculate_discount_for_customer 1;
PRINT @discount
GO

-------------------------
-- Четвёртая процедура --
-------------------------

CREATE PROCEDURE calculate_full_expenses_month
    @date DATE,
    @expenses FLOAT OUTPUT
AS BEGIN
    SET @expenses = 0.0;

    DECLARE @salary INT;
    SELECT @salary=SUM(salary) FROM Drivers;

    DECLARE @gas_price FLOAT = 0.0;
    SELECT @gas_price=SUM(gas_consumption / 100.0 * distance)
    FROM Deliveries
    JOIN Routes ON Deliveries.route_id = Routes.id
    JOIN Vehicles ON Deliveries.vehicle_id = Vehicles.id
    WHERE DATEPART(year, date) = DATEPART(year, @date) AND
          DATEPART(month, date) = DATEPART(month, @date);
    SET @gas_price = IIF(@gas_price IS NULL, 0.0, @gas_price);

    SET @expenses = CAST(@salary AS FLOAT) + @gas_price;
END
GO

DROP PROCEDURE calculate_full_expenses_month
GO

DECLARE @expenses FLOAT;
EXEC calculate_full_expenses_month '2021-12-01', @expenses OUTPUT;
PRINT CAST(@expenses AS INT)
GO

---------------------
-- Пятая процедура --
---------------------

CREATE PROCEDURE calculate_full_returns_month
    @date DATE,
    @returns FLOAT OUTPUT
AS SELECT @returns=SUM(amount) FROM Payments
   WHERE DATEPART(year, date) = DATEPART(year, @date) AND
         DATEPART(month, date) = DATEPART(month, @date);
GO

DROP PROCEDURE calculate_full_returns_month
GO

DECLARE @returns FLOAT;
EXEC calculate_full_returns_month '2021-12-01', @returns OUTPUT;
PRINT CAST(@returns AS INT)
GO