-
Notifications
You must be signed in to change notification settings - Fork 0
/
07.Functions Triggers And Transactions.sql
671 lines (476 loc) · 14 KB
/
07.Functions Triggers And Transactions.sql
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
Functions Triggers And Transactions Homework
01. Employees with Salary Above 35000
create proc usp_GetEmployeesSalaryAbove35000
as select FirstName, LastName from Employees
where Salary > 35000
02. Employees with Salary Above Number
create proc usp_GetEmployeesSalaryAboveNumber (@parameter money)
as select FirstName, LastName from Employees
where Salary >= @parameter
03. Town Names Starting With
create proc usp_GetTownsStartingWith (@parameter varchar(max))
as select Name from Towns
where SUBSTRING(Name,1,len(@parameter)) = @parameter
04. Employees from Town
create proc usp_GetEmployeesFromTown (@townName varchar(max))
as select FirstName, LastName from Employees as e
join Addresses as a
on e.AddressID = a.AddressID
join Towns as t
on a.TownID = t.TownID
where t.Name = @townName
05. Salary Level Function
create function ufn_GetSalaryLevel (@salary MONEY)
returns nvarchar(10) as
begin
declare @SalaryLevel nvarchar(20)
if (@salary < 30000)
set @SalaryLevel = 'Low'
else if (@salary between 30000 and 50000)
set @SalaryLevel = 'Average'
else set @SalaryLevel = 'High'
return @SalaryLevel
end
06. Employees by Salary Level
create procedure usp_EmployeesBySalaryLevel (@parameter nvarchar(10))
as
begin
select s.FirstName as 'First Name', s.LastName as 'Last Name'
from (SELECT FirstName, LastName, Salary, dbo.ufn_GetSalaryLevel(Salary) as SalaryLevel
FROM Employees) as s
where s.SalaryLevel = @parameter
end
07. Define Function
create function ufn_IsWordComprised (@setOfLetters nvarchar(20), @word nvarchar(20))
returns bit
as
begin
declare @comprised bit = 1
declare @index int = 1
while (@comprised = 1) and (@index <= len(@word))
begin
if(charindex(lower(substring(@word, @index, 1)), lower(@setOfLetters)) not between 1 and len(@setOfLetters))
begin
set @comprised = 0
end
else set @index += 1
end
return @comprised
end
08. Delete Employees and Departments
begin tran
alter table [dbo].[EmployeesProjects]
drop constraint [FK_EmployeesProjects_Employees]
alter table Departments
drop constraint FK_Departments_Employees
alter table Employees
drop constraint FK_Employees_Employees
delete from Employees
where DepartmentID in (7,8)
delete from Departments
where DepartmentID in (7,8)
09. Employees with Three Projects
create proc usp_AssignProject(@emloyeeId int, @projectID int)
as
begin
begin tran
insert into EmployeesProjects(EmployeeID,ProjectID)
values(@emloyeeId, @projectID)
if (select count(EmployeeID) from EmployeesProjects where EmployeeID = @emloyeeId) > 3
begin
raiserror ('The employee has too many projects!', 16, 1)
rollback
end
commit
end
10. Find Full Name
create proc usp_GetHoldersFullName
as
begin
select FirstName + ' ' + LastName as 'Full Name' from AccountHolders
end
11. People with Balance Higher Than
create proc usp_GetHoldersWithBalanceHigherThan (@num money) as
begin
select ah.FirstName, ah.LastName from AccountHolders as ah
join Accounts as c on ah.Id = c.AccountHolderId
group by ah.FirstName, ah.LastName
having sum(c.Balance) > @num
end
12. Future Value Function
create function ufn_CalculateFutureValue (@sum money, @yearlyInterestRate float, @years int)
returns money
as
begin
declare @futureValue money = @sum * (power((1 + @yearlyInterestRate),@years))
return @futureValue
end
13. Calculating Interest
create proc usp_CalculateFutureValueForAccount (@AccountId int, @interestRate money)
as
begin
select a.Id as [Account Id],
ah.FirstName,
ah.LastName,
sum(a.Balance) as [Current Balance],
dbo.[ufn_CalculateFutureValue](sum(a.Balance), @interestRate, 5)
from AccountHolders as ah
join Accounts as a
on ah.Id = a.AccountHolderId
where a.Id = @AccountId
group by a.Id, ah.FirstName, ah.LastName
end
14. Deposit Money Procedure
create proc usp_DepositMoney (@AccountId int, @moneyAmount money)
as
begin
begin tran
update Accounts
set Balance = Balance + @moneyAmount
where Accounts.Id = @AccountId
commit
end
15. Withdraw Money Procedure
create proc usp_WithdrawMoney (@AccountId int, @moneyAmount money)
as
begin
begin tran
update Accounts
set Balance = Balance - @moneyAmount
where Accounts.Id = @AccountId
commit
end
16. Money Transfer
create proc usp_TransferMoney (@senderId int, @recieverId int, @amount money)
as
begin
begin tran
exec [dbo].[usp_WithdrawMoney] @senderId,@amount
exec [dbo].[usp_DepositMoney] @recieverId, @amount
if (select Balance from Accounts where Accounts.Id = @senderId) < 0
rollback
else
commit
end
17. Create Table Logs
create trigger tr_SumChanges on [Accounts] after update
as
begin
insert into [Logs] (AccountId, OldSum, NewSum)
select i.Id, d.Balance, i.Balance from inserted as i
inner join deleted as d
on i.AccountHolderId = d.AccountHolderId
end
18. Create Table Emails
create trigger tr_LogToEmail on Logs after insert
as
begin
insert into NotificationEmails
(Recipient, Subject, Body)
select AccountId,
'Balance change for account: '
+ convert(varchar(10), AccountId),
'On ' + convert(varchar(30), getdate()) + ' your balance was changed from '
+ convert(varchar(30), OldSum) + ' to '
+ convert(varchar(30), NewSum)
from Logs
end
19. *Cash in User Games Odd Rows
CREATE FUNCTION ufn_CashInUsersGames (@gameName NVARCHAR(50))
RETURNS @Result TABLE(
SumCash MONEY
)
AS
BEGIN
INSERT INTO @Result
SELECT SUM(sc.Cash) as SumCash
FROM
(SELECT Cash,
ROW_NUMBER() OVER(ORDER BY Cash DESC) AS RowNumber
FROM UsersGames ug
RIGHT JOIN Games g
ON ug.GameId = g.Id
WHERE g.Name = @gameName) sc
WHERE RowNumber % 2 != 0
RETURN
END
21. *Massive Shopping
BEGIN TRANSACTION
DECLARE @sum1 MONEY = (SELECT SUM(i.Price)
FROM Items i
WHERE MinLevel BETWEEN 11 AND 12)
IF (SELECT Cash FROM UsersGames WHERE Id = 110) < @sum1
ROLLBACK
ELSE BEGIN
UPDATE UsersGames
SET Cash = Cash - @sum1
WHERE Id = 110
INSERT INTO UserGameItems (UserGameId, ItemId)
SELECT 110, Id
FROM Items
WHERE MinLevel BETWEEN 11 AND 12
COMMIT
END
BEGIN TRANSACTION
DECLARE @sum2 MONEY = (SELECT SUM(i.Price)
FROM Items i
WHERE MinLevel BETWEEN 19 AND 21)
IF (SELECT Cash FROM UsersGames WHERE Id = 110) < @sum2
ROLLBACK
ELSE BEGIN
UPDATE UsersGames
SET Cash = Cash - @sum2
WHERE Id = 110
INSERT INTO UserGameItems (UserGameId, ItemId)
SELECT 110, Id
FROM Items
WHERE MinLevel BETWEEN 19 AND 21
COMMIT
END
SELECT i.Name AS 'Item Name'
FROM UserGameItems ugi
JOIN Items i
ON ugi.ItemId = i.Id
WHERE ugi.UserGameId = 110
22. Number of Users for Email Provider
SELECT SUBSTRING(Email, CHARINDEX('@', Email)+1, len(Email)) AS [Email Provider],
COUNT(Email) AS [Number Of Users]
FROM Users
GROUP BY SUBSTRING(Email, CHARINDEX('@', Email)+1, len(Email))
ORDER BY COUNT(Email) DESC, SUBSTRING(Email, CHARINDEX('@', Email)+1, len(Email))
23. All Users in Games
SELECT g.Name, gt.Name AS [Game Type],
u.Username, ug.Level, ug.Cash, c.Name
FROM Games g
JOIN GameTypes gt
ON gt.Id = g.GameTypeId
JOIN UsersGames ug
ON ug.GameId = g.Id
JOIN Users u
ON u.Id = ug.UserId
JOIN Characters c
ON ug.CharacterId = c.Id
ORDER BY ug.Level DESC, u.Username, g.Name
24. Users in Games with Their Items
SELECT u.Username, g.Name AS Game, COUNT(i.Name), SUM(i.Price)
FROM Users u
JOIN UsersGames ug
ON u.Id = ug.UserId
JOIN Games g
ON ug.GameId = g.Id
JOIN UserGameItems ugi
ON ugi.UserGameId = ug.Id
JOIN Items i
ON i.Id = ugi.ItemId
GROUP BY u.Username, g.Name
HAVING COUNT(i.Name) >= 10
ORDER BY COUNT(i.Name) DESC,
SUM(i.Price) DESC,
u.Username
25. * User in Games with Their Statistics
SELECT u.Username, g.Name AS Game, MAX(c.Name) AS Character,
SUM(its.Strength) + MAX(gts.Strength) + MAX(cs.Strength) AS Strength,
SUM(its.Defence) + MAX(gts.Defence) + MAX(cs.Defence) AS Defence,
SUM(its.Speed) + MAX(gts.Speed) + MAX(cs.Speed) as Speed,
SUM(its.Mind) + MAX(gts.Mind) + MAX(cs.Mind) AS Mind,
SUM(its.Luck) + MAX(gts.Luck) + MAX(cs.Luck) AS Luck
FROM Users u
JOIN UsersGames ug
ON u.Id = ug.UserId
JOIN Games g
ON ug.GameId = g.Id
JOIN GameTypes gt
ON gt.Id = g.GameTypeId
JOIN [dbo].[Statistics] gts
ON gts.Id = gt.BonusStatsId
JOIN Characters c
ON ug.CharacterId = c.Id
JOIN [dbo].[Statistics] cs
ON cs.Id = c.StatisticId
JOIN UserGameItems ugi
ON ugi.UserGameId = ug.Id
JOIN Items i
ON i.Id = ugi.ItemId
JOIN [dbo].[Statistics] its
ON its.Id = i.StatisticId
GROUP BY u.Username, g.Name
ORDER BY Strength DESC, Defence DESC, Speed DESC, Mind DESC, Luck DESC
26. All Items with Greater than Average Statistics
SELECT i.Name, i.Price, i.MinLevel,
s.Strength, s.Defence, s.Speed, s.Luck, s.Mind
FROM Items i
JOIN [Statistics] s
ON i.StatisticId = s.Id
WHERE s.Speed > (SELECT AVG(s.Speed)
FROM Items i
JOIN [Statistics] s
ON i.StatisticId = s.Id
)
AND s.Luck > (SELECT AVG(s.Luck)
FROM Items i
JOIN [Statistics] s
ON i.StatisticId = s.Id
)
AND s.Mind > (SELECT AVG(s.Mind)
FROM Items i
JOIN [Statistics] s
ON i.StatisticId = s.Id
)
ORDER BY i.Name
27. Display All Items about Forbidden Game Type
SELECT i.Name AS Item, i.Price, i.MinLevel,
gt.Name AS [Forbidden Game Type]
FROM Items i
LEFT JOIN GameTypeForbiddenItems gtfi
ON gtfi.ItemId = i.Id
LEFT JOIN GameTypes gt
ON gt.Id = gtfi.GameTypeId
ORDER BY [Forbidden Game Type] DESC,
i.Name
28. Buy Items for User in Game
DECLARE @sumCash MONEY = (SELECT SUM(Price)
FROM Items
WHERE Name IN ('Blackguard', 'Bottomless Potion of Amplification',
'Eye of Etlich (Diablo III)', 'Gem of Efficacious Toxin',
'Golden Gorget of Leoric', 'Hellfire Amulet'))
BEGIN TRAN
IF (SELECT SUM(Cash) FROM UsersGames
WHERE UserId = (SELECT Id FROM Users
WHERE Username = 'Alex')) < @sumCash
ROLLBACK
ELSE
UPDATE UsersGames
SET Cash = Cash - @sumCash
WHERE UserId = (SELECT Id FROM Users
WHERE Username = 'Alex')
INSERT INTO UserGameItems (ItemId, UserGameId)
(SELECT i.Id, 235
FROM Items i
WHERE Name IN ('Blackguard', 'Bottomless Potion of Amplification',
'Eye of Etlich (Diablo III)', 'Gem of Efficacious Toxin',
'Golden Gorget of Leoric', 'Hellfire Amulet'))
COMMIT
SELECT u.Username, g.Name, ug.Cash, i.Name AS [Item Name]
FROM UserGameItems ugi
JOIN Items i
ON ugi.ItemId = i.Id
JOIN UsersGames ug
ON ug.Id = ugi.UserGameId
JOIN Users u
ON ug.UserId = u.Id
JOIN Games g
ON ug.GameId = g.Id
WHERE g.Name = 'Edinburgh'
ORDER BY i.Name
29. Peaks and Mountains
SELECT p.PeakName, m.MountainRange AS Mountain, p.Elevation
FROM Peaks p
JOIN Mountains m
ON p.MountainId = m.Id
ORDER BY p.Elevation DESC, p.PeakName
30. Peaks with Mountain, Country and Continent
SELECT p.PeakName, m.MountainRange, c.CountryName, con.ContinentName
FROM Peaks p
JOIN Mountains m
ON p.MountainId = m.Id
JOIN MountainsCountries mc
ON mc.MountainId = m.Id
JOIN Countries c
ON mc.CountryCode = c.CountryCode
JOIN Continents con
ON con.ContinentCode = c.ContinentCode
ORDER BY p.PeakName, c.CountryName
31. Rivers by Country
SELECT c.CountryName, con.ContinentName,
ISNULL(COUNT(r.Id), 0) AS RiversCount,
ISNULL(SUM(r.Length), 0) AS TotalLength
FROM Countries c
JOIN Continents con
ON con.ContinentCode = c.ContinentCode
LEFT JOIN CountriesRivers cr
ON c.CountryCode = cr.CountryCode
LEFT JOIN Rivers r
ON cr.RiverId = r.Id
GROUP BY c.CountryName, con.ContinentName
ORDER BY RiversCount DESC, TotalLength DESC, c.CountryName
32. Count of Countries by Currency
SELECT c.CurrencyCode, c.Description AS Currency,
COUNT(ctr.CountryCode) AS NumberOfCountries
FROM Currencies c
LEFT JOIN Countries ctr
ON c.CurrencyCode = ctr.CurrencyCode
GROUP BY c.CurrencyCode, c.Description
ORDER BY NumberOfCountries DESC, c.Description
33. Population and Area by Continent
SELECT cnt.ContinentName,
SUM(cntr.AreaInSqKm) AS CountriesArea,
SUM(CAST (cntr.Population AS BIGINT)) AS CountriesPopulation
FROM Countries cntr
JOIN Continents cnt
ON cntr.ContinentCode = cnt.ContinentCode
GROUP BY cnt.ContinentName
ORDER BY CountriesPopulation DESC
34. Monasteries by Country
CREATE TABLE Monasteries(
Id INT IDENTITY PRIMARY KEY,
Name NVARCHAR(50),
CountryCode CHAR(2)
FOREIGN KEY (CountryCode) REFERENCES Countries(CountryCode)
)
INSERT INTO Monasteries(Name, CountryCode) VALUES
('Rila Monastery “St. Ivan of Rila”', 'BG'),
('Bachkovo Monastery “Virgin Mary”', 'BG'),
('Troyan Monastery “Holy Mother''s Assumption”', 'BG'),
('Kopan Monastery', 'NP'),
('Thrangu Tashi Yangtse Monastery', 'NP'),
('Shechen Tennyi Dargyeling Monastery', 'NP'),
('Benchen Monastery', 'NP'),
('Southern Shaolin Monastery', 'CN'),
('Dabei Monastery', 'CN'),
('Wa Sau Toi', 'CN'),
('Lhunshigyia Monastery', 'CN'),
('Rakya Monastery', 'CN'),
('Monasteries of Meteora', 'GR'),
('The Holy Monastery of Stavronikita', 'GR'),
('Taung Kalat Monastery', 'MM'),
('Pa-Auk Forest Monastery', 'MM'),
('Taktsang Palphug Monastery', 'BT'),
('Sümela Monastery', 'TR')
UPDATE Countries
SET IsDeleted = 1
WHERE CountryCode IN (SELECT r.CountryCode
FROM (SELECT c.CountryCode, COUNT(cr.RiverId) AS CountR
FROM Countries c
JOIN CountriesRivers cr
ON c.CountryCode = cr.CountryCode
GROUP BY c.CountryCode
HAVING COUNT(cr.RiverId) > 3) r
)
SELECT m.Name AS Monastery, c.CountryName AS Country
FROM Monasteries m
JOIN Countries c
ON m.CountryCode = c.CountryCode
WHERE c.IsDeleted != 1 OR c.IsDeleted IS NULL
ORDER BY Monastery
35. Monasteries by Continents and Countries
UPDATE Countries
SET CountryName = 'Burma'
WHERE CountryName = 'Myanmar'
INSERT INTO Monasteries(Name, CountryCode)
SELECT 'Hanga Abbey', CountryCode
FROM Countries
WHERE CountryName = 'Tanzania'
INSERT INTO Monasteries(Name, CountryCode)
SELECT 'Myin-Tin-Daik', CountryCode
FROM Countries
WHERE CountryName = 'Myanmar'
SELECT cnt.ContinentName, cntr.CountryName,
COUNT(m.Id) AS MonasteriesCount
FROM Countries cntr
LEFT JOIN Continents cnt
ON cnt.ContinentCode = cntr.ContinentCode
LEFT JOIN Monasteries m
ON cntr.CountryCode = m.CountryCode
WHERE cntr.IsDeleted != 1 OR cntr.IsDeleted IS NULL
GROUP BY cnt.ContinentName, cntr.CountryName
ORDER BY MonasteriesCount DESC, cntr.CountryName