Advertisement
Ladies_Man

#DB Lab8 (Proc, Cursors, Funcs) COMPLETE

Dec 1st, 2015
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 7.45 KB | None | 0 0
  1. --Лабораторная работа №8. Хранимые процедуры, курсоры и пользовательские функции
  2.  
  3.  
  4. --1.Создать хранимую процедуру, производящую выборку из некоторой таблицы и возвращающую результат выборки в виде курсора.
  5. --2.Модифицировать хранимую процедуру п.1. таким образом, чтобы выборка осуществлялась с формированием столбца, значение которого формируется пользовательской функцией.
  6. --3.Создать хранимую процедуру, вызывающую процедуру п.1., осуществляющую прокрутку возвращаемого курсора и выводящую сообщения,
  7.     --сформированные из записей при выполнении условия, заданного еще одной пользовательской функцией.
  8. --4.Модифицировать хранимую процедуру п.2. таким образом, чтобы выборка формировалась с помощью табличной функции.
  9.  
  10.  
  11. use master;
  12. go
  13. if DB_ID (N'lab8') is null
  14.         create database lab8
  15.         on (
  16.                 NAME = lab8dat,
  17.                 FILENAME = 'C:\Users\me\Documents\DB_Labs\lab8\lab8dat.mdf',
  18.                 SIZE = 10,
  19.                 MAXSIZE = UNLIMITED,
  20.                 FILEGROWTH = 5
  21.                 )
  22.         log on (
  23.                 NAME = lab8log,
  24.                 FILENAME = 'C:\Users\me\Documents\DB_Labs\lab8\lab8log.ldf',
  25.                 SIZE = 5,
  26.                 MAXSIZE = 20,
  27.                 FILEGROWTH = 5
  28.                 );
  29. go
  30.  
  31. use lab8;
  32. go
  33. if OBJECT_ID(N'dbo.books', N'U') is not null
  34.     drop table dbo.books;
  35. go
  36. create table dbo.books (
  37.     bid         int         not null    IDENTITY(1, 1),
  38.     book_name       varchar(254)        not null,
  39.     author_lastname     varchar(35)     not null,
  40.     author_initials     varchar(35)     null,
  41.     year            int         not null,
  42.     genre           varchar(254)        null,
  43.  
  44.     PRIMARY KEY (bid)
  45. );
  46. go
  47.  
  48. insert into dbo.books(book_name, author_lastname, author_initials, genre, year)
  49.     values
  50.         ('the lord of the rings', 'tolkien', 'john r. r.', 'high fantasy', 1954),
  51.         ('the hobbit, or there and back again', 'tolkien', 'john r. r.', 'high fantasy', 1937),
  52.         ('a song of ice and fire', 'martin', 'george r. r.', 'epic fantasy', 1996),
  53.         ('1984', 'orwell', 'george', 'dystopian', 1949),
  54.         ('the martian', 'weir', 'andy', 'science fiction', 2011),
  55.         ('fahrenheit 451', 'bradbury', 'raymond d.', 'dystopian', 1953),
  56.         ('the time machine', 'wells', 'herbert g.', 'science fiction', 1895),
  57.         ('the war of the worlds', 'wells', 'herbert g.', 'science fiction', 1897),
  58.         ('the da vinci code', 'brown', 'daniel', 'mystery-detective', 2003);
  59. go
  60.  
  61. select * from books;
  62. go
  63.  
  64.  
  65. --==============================================================
  66. --------------------------FUNCTIONS-----------------------------
  67. --==============================================================
  68. if OBJECT_ID(N'dbo.get_antiquity', N'FN') is not null
  69.     drop function dbo.get_antiquity;
  70. go
  71. create function dbo.get_antiquity(@release_year int)
  72.     returns int
  73.     with execute as caller
  74.     as
  75.     begin
  76.         declare @current_date datetime = GETDATE();
  77.         declare @current_year int, @year_delta int;
  78.  
  79.         set @current_year = YEAR(@current_date);
  80.         set @year_delta = @current_year - @release_year;
  81.    
  82.         return @year_delta;
  83.     end
  84. go
  85.  
  86.  
  87. if OBJECT_ID(N'dbo.compare_years', N'FN') is not null
  88.     drop function dbo.compare_years;
  89. go
  90. create function dbo.compare_years(@compare_what int, @compare_to int)
  91.     returns int
  92.     with execute as caller
  93.     as
  94.     begin
  95.         declare @retval int;
  96.  
  97.         if (@compare_what >= @compare_to)
  98.             set @retval = 1;
  99.         else
  100.             set @retval = 0;
  101.  
  102.         return @retval;
  103.     end
  104. go
  105.  
  106.  
  107. --==============================================================
  108. --------------------------PROCEDURES----------------------------
  109. --==============================================================
  110. --Создать хранимую процедуру, производящую выборку из некоторой таблицы и возвращающую результат выборки в виде курсора.
  111.  
  112. --Модифицировать хранимую процедуру п.1. таким образом, чтобы выборка осуществлялась
  113. --с формированием столбца, значение которого формируется пользовательской функцией.
  114.  
  115. if OBJECT_ID(N'dbo.sub_proc', N'P') is not null
  116.     drop procedure dbo.sub_proc
  117. go
  118. CREATE PROCEDURE dbo.sub_proc
  119.     @curs CURSOR VARYING OUTPUT
  120. AS
  121.     SET NOCOUNT ON;
  122.     SET @curs = CURSOR
  123.     SCROLL STATIC FOR              
  124.         select book_name, author_lastname, dbo.get_antiquity(year)  --custom column
  125.         from dbo.books
  126.         OPTION (MAXRECURSION 0);    --in case of recursion depth err
  127.     OPEN @curs;
  128. go
  129.  
  130.  
  131. --Создать хранимую процедуру, вызывающую процедуру п.1.,
  132. --осуществляющую прокрутку возвращаемого курсора и выводящую сообщения,
  133. --сформированные из записей при выполнении условия, заданного еще одной пользовательской функцией.
  134.  
  135. if OBJECT_ID(N'dbo.external_proc', N'P') is not null
  136.     drop procedure dbo.external_proc
  137. go
  138. create procedure dbo.external_proc
  139. AS
  140.     declare @ext_curs cursor;
  141.     declare @t_bkname varchar(254);
  142.     declare @t_auth varchar(35);
  143.     declare @t_antiq int;
  144.  
  145.     exec dbo.sub_proc @curs = @ext_curs OUTPUT;
  146.  
  147.     --always use fetch_next before actual fetch according to MSDN
  148.     FETCH NEXT FROM @ext_curs INTO @t_bkname, @t_auth, @t_antiq;
  149.     print 'First Fetch: "' + @t_bkname + '"'
  150.  
  151.     WHILE (@@FETCH_STATUS = 0)
  152.     BEGIN
  153.         IF (dbo.compare_years(@t_antiq, 40) = 1)
  154.             print '"' + @t_bkname + '" was written by ' + @t_auth + ', ' + CAST(@t_antiq as varchar) + ' years ago'
  155.         FETCH NEXT FROM @ext_curs
  156.         INTO @t_bkname, @t_auth, @t_antiq;
  157.     END
  158.  
  159.     CLOSE @ext_curs;
  160.     DEALLOCATE @ext_curs;
  161. GO
  162.  
  163. exec dbo.external_proc
  164. go
  165.  
  166.  
  167. --Модифицировать хранимую процедуру п.2. таким образом,
  168. --чтобы выборка формировалась с помощью табличной функции.
  169.  
  170. IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id(N'dbo.get_classic')
  171.     AND xtype IN (N'FN', N'IF', N'TF'))
  172.     DROP FUNCTION dbo.get_classic
  173. go
  174. --table inline function: CREATE FUNCTION ... RETURNS TABLE AS RETURN ( SELECT ... );
  175. create function dbo.get_classic()
  176.     --not inline function:
  177.     returns @tt table
  178.     (
  179.         classic_book_name nvarchar(254),
  180.         classic_book_year int
  181.     )
  182.     as
  183.     begin
  184.         insert @tt
  185.             select books.book_name, books.year
  186.             from dbo.books
  187.             where books.year < 1980
  188.         return
  189.     end
  190. go
  191.  
  192. alter procedure dbo.sub_proc
  193.     @curs cursor VARYING OUTPUT
  194. as
  195. begin
  196.     set nocount on;
  197.     set @curs = cursor
  198.     scroll static for
  199.         select classic_book_name, classic_book_year
  200.         from dbo.get_classic();     --table function
  201.     open @curs;
  202. end
  203. go
  204.  
  205. declare @another_curs cursor;
  206.  
  207. EXEC dbo.sub_proc @curs = @another_curs OUTPUT;
  208. fetch next from @another_curs;
  209. while (@@FETCH_STATUS = 0)
  210. begin
  211.     fetch next from @another_curs;
  212. end
  213. close @another_curs;
  214. deallocate @another_curs;
  215. go
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement