в ms sql server чем отличаются хранимые процедуры и функции
Чем отличаются функции от хранимых процедур в T-SQL (Microsoft SQL Server)
Приветствую всех посетителей сайта Info-Comp.ru! Сегодня мы с Вами поговорим о том, чем же отличаются функции от хранимых процедур в Microsoft SQL Server, и для наглядности сформируем итоговую таблицу отличий.
Функции и хранимые процедуры T-SQL
В Microsoft SQL Server существуют такие объекты базы данных, как функции и хранимые процедуры, которые используются для хранения неких уже реализованных алгоритмов на языке T-SQL.
Примечание! В данном материале речь идет о пользовательских функциях и хранимых процедурах, не о системных, которые уже реализованы в SQL Server, а о тех, которые создаем мы с Вами, т.е. программисты T-SQL.
Функции и хранимые процедуры используются в языке T-SQL для реализации бизнес логики, упрощения сложных SQL запросов, а также для написания различных инструкций администрирования баз данных и сервера, которые периодически необходимо выполнять.
Иными словами, функции и хранимые процедуры – это своего рода мини программы внутри базы данных, они помогают нам реализовывать нужные нам алгоритмы и хранить их в базе данных. Кроме этого, функции и хранимые процедуры позволяют декомпозировать одну глобальную задачу на несколько мелких, тем самым упрощая решение этой задачи и дальнейшее сопровождение этого решения, так как весь алгоритм становится модульным и более гибким.
У начинающих может возникнуть вопрос – а чем отличаются функции от процедур? Или это одно и то же?
Конечно же, это не одно и то же, и между этими понятиями, в контексте языка T-SQL, есть нескольких ключевых отличный.
Отличия функций от хранимых процедур в T-SQL
Давайте перейдем к рассмотрению основных отличный функций от хранимых процедур, а чтобы было более наглядно, сделаем это в виде таблицы.
Функция
Хранимая процедура
Операторы DML (INSERT, UPDATE, DELETE) для модификации данных использовать нельзя.
На сегодня это все, надеюсь, материал был Вам полезен, пока!
Назначение хранимых процедур в языке T-SQL (Microsoft SQL Server)
Приветствую Вас на сайте Info-Comp.ru! Из данного материала Вы узнаете, для чего нужны хранимые процедуры в языке T-SQL, мы рассмотрим основные возможности хранимых процедур и преимущества их использования.
Хранимые процедуры в T-SQL
Хранимая процедура – это объект базы данных, который хранит набор инструкций языка T-SQL, реализующих определённый алгоритм.
Хранимые процедуры используются в языке T-SQL для реализации бизнес логики, каких-то алгоритмов, расчетов, а также для написания различных инструкций администрирования баз данных и сервера, которые периодически необходимо выполнять.
Иными словами, хранимые процедуры – это своего рода программы внутри базы данных, которые хранят реализованный нами алгоритм, и в случае запуска этих программ выполняют этот алгоритм.
Примечание! В данном материале речь идет о пользовательских хранимых процедурах, которые создаем мы с Вами, т.е. программисты T-SQL.
Назначение хранимых процедур в T-SQL
Чтобы ответить на вопрос: для чего нужны хранимые процедуры? и определить их назначение, необходимо рассмотреть возможности, которые нам предоставляют хранимые процедуры, и те преимущества, которые мы получим, если будем их использовать. Именно это и определяет назначение хранимых процедур, т.е. для чего они созданы.
Возможности хранимых процедур
Преимущества хранимых процедур
Повышение безопасности
Использование хранимых процедур повышает безопасность по нескольким причинам:
Устранение дублирования кода
SQL код, включающий многошаговые операции с базой данных, который многократно используется в приложении в разных местах, можно вынести в хранимую процедуру, тем самым устранить необходимость копирования одного и того же кода. Как результат, у Вас уменьшится общий объем кода за счет отсутствия повторяющихся участков кода.
Легкое сопровождение кода
Когда весь SQL код и заложенный в нем алгоритм вынесен в хранимые процедуры, а клиентское приложение лишь осуществляет вызов этих процедур, то сопровождать такое приложение становится гораздо легче. Ведь в случае возникновения необходимости внести изменение в алгоритм работы с данными, который заложен в хранимой процедуре, достаточно один раз внести изменение в базу данных в код хранимой процедуры. Иными словами, нет необходимости вносить изменения в само клиентское приложение, перекомпилировать и осуществлять обновление.
Кроме этого вынесение всего SQL кода в хранимые процедуры снизит уровень несогласованности кода клиентского приложения, и таких ситуаций возникать не будет, когда в одном месте SQL код выполняет одни изменения в базе данных, а вроде бы тот же самый SQL код, но в другом месте, выполняет совершенно другие изменения в базе данных. С хранимыми процедурами Вы будете вносить изменения только в одном месте – в исходном коде хранимой процедуры.
Повышение производительности
Microsoft SQL Server компилирует хранимую процедуру и создает план выполнения один раз, а затем повторно использует этот план выполнения. Это приводит к повышению производительности в случае многократного вызова хранимой процедуры, ведь теперь обработчику запросов не нужно создавать новый план и поэтому обработка процедуры занимает меньше времени.
Примечание! Если в таблицах и в данных, с которыми работает хранимая процедура, произошли значительные изменения, то наличие предварительно скомпилированного плана наоборот может вызвать замедление работы процедуры. В этом случае необходимо принудительно перекомпилировать процедуру, и тем самым создать новый план выполнения.
Сокрытие сложности
В разработке приложения нередко участвуют достаточно много разработчиков, а если говорить о крупных информационных системах, то разработчики могут исчисляться и сотнями. При этом одни программисты разрабатывают интерфейс клиентского приложения, а другие разрабатывают базу данных и всю логику работы с ней.
И в таких ситуациях разработчикам, которые работают с интерфейсом клиентского приложения, совсем необязательно знать алгоритм выполнения определённых действий в базе данных, который заложен в SQL инструкциях. Более того, они не должны его знать.
Хранимые процедуры как раз и скрывают алгоритм действий в базе данных и всю его сложность. Иными словами, если, например, разработчику клиентского приложения потребовалось использовать функционал добавления нового пользователя этого приложения, то он должен знать только название хранимой процедуры и описание ее параметров, а что конкретно она там делает и как именно создает пользователя, он знать не должен.
Использование хранимых процедур T-SQL является преимуществом и для разработчиков интерфейса приложения, так как в этом случае им просто легче программировать, им не нужно писать запутанные SQL инструкции, они могут просто вызывать хранимые процедуры, более того, так у них формируется полноценная абстракция их классов, в случае с ООП.
Снижение сетевого трафика между клиентами и сервером
Использование хранимых процедур позволяет существенно сократить сетевой трафик между сервером и клиентом, так как по сети отправляется только вызов на выполнение хранимой процедуры. Иными словами, без инкапсуляции кода, предоставляемой процедурой, по сети нам бы пришлось пересылать все строки кода, которых может быть достаточно много.
Подведение итогов
Давайте подведем итог на основе всего вышесказанного и сформулируем итоговое назначение хранимых процедур в языке T-SQL.
Тема 9. Хранимые процедуры как базовый компонент серверной части информационных систем
Оглавление
Цель: ознакомиться с технологией написания, отладки и использования хранимых процедур на сервере баз данных.
Задачи:
9.1. Создание хранимых процедур
С точки зрения приложений, работающих с БД, хранимые процедуры (Stored Procedure) — это подпрограммы, которые выполняются на сервере. По отношению к БД это объекты, которые создаются и хранятся в БД. Они могут быть вызваны из клиентских приложений. При этом одна процедура может быть использована в любом количестве клиентских приложений, что позволяет существенно сэкономить трудозатраты на создание прикладного программного обеспечения и эффективно применять стратегию повторного использования кода. Так же, как и любые процедуры в стандартных языках программирования, хранимые процедуры могут иметь входные и выходные параметры или не иметь их вовсе.
Хранимые процедуры могут быть активизированы не только пользовательскими приложениями, но и триггерами.
Хранимые процедуры пишутся на специальном встроенном языке программирования, они могут включать любые операторы SQL, а также включают некоторый набор операторов, управляющих ходом выполнения программ, которые во многом схожи с подобными операторами процедурно ориентированных языков программирования. В коммерческих СУБД для написания текстов хранимых процедур используются собственные языки программирования. Так, в СУБД Oracle для этого используется язык PL /SQL, а в MS SQL Server и System11 фирмы Sybase используется язык Transact SQL. В последних версиях Oracle объявлено использование языка Java для написания хранимых процедур.
Хранимые процедуры являются объектами БД. Каждая хранимая процедура компилируется при первом выполнении, в процессе компиляции строится оптимальный план выполнения процедуры. Описание процедуры совместно с планом ее выполнения хранится в системных таблицах БД.
Хранимая процедура — это набор команд, хранимый на сервере и выполняемый как единое целое.
Для создания хранимой процедуры применяется оператор SQL CREATE PROCEDURE.
По умолчанию выполнить хранимую процедуру может только ее владелец, которым является владелец БД, и создатель хранимой процедуры. Однако владелец хранимой процедуры может делегировать права на ее запуск другим пользователям.
Имя хранимой процедуры является идентификатором в языке программирования, на котором она пишется, и должно удовлетворять всем требованиям, которые предъявляются к идентификаторам в данном языке.
В MS SQL Server хранимая процедура создается оператором:
| RECOMPILE, ENCRYPTION >]
Здесь необязательное ключевое слово VARYING определяет, что в качестве выходного параметра используется результирующий набор — только для типа cursor
OUTPUT — говорит о том, что указанный параметр является (вернее может быть использован) выходным.
Ключевое слово RECOMPILE определяет режим компиляции создаваемой хранимой процедуры. Если задано ключевое слово RECOMPILE, то процедура будет перекомпилироваться каждый раз, когда она будет вызываться на исполнение. Это может резко замедлить исполнение процедуры. Но с другой стороны, если данные, обрабатываемые данной хранимой процедурой, настолько динамичны, что предыдущий план исполнения, составленный при ее первом вызове, может быть абсолютно неэффективен при последующих вызовах, то стоит применять данный параметр при создании этой процедуры.
Ключевое слово ENCRYPTION определяет режим, при котором исходный текст хранимой процедуры не сохраняется в БД. Такой режим применяется для того, чтобы сохранить авторское право на интеллектуальную продукцию, которой и являются хранимые процедуры. Часто такой режим применяется, когда вы ставите готовую базу заказчику и не хотите, чтобы исходные тексты разработанных вами хранимых процедур были бы доступны администратору БД, работающему у заказчика. Однако надо помнить, что если вы захотите отредактировать текст хранимой процедуры сами, то вы его тоже не сможете извлечь из БД, его надо будет хранить отдельно, в некотором текстовом файле — и это не самое плохое. Но вот в случае восстановления БД после серьезной аварии для перекомпиляции потребуются первоначальные исходные тексты всех хранимых процедур. Поэтому защита вещь хорошая, но она усложняет сопровождение и модификацию хранимых процедур.
FOR REPLICATION — ключевые слова, показывающие, что эта процедура создается только для репликации.
Однако кроме имени хранимой процедуры все остальные параметры являются необязательными. Процедуры могут быть процедурами или процедурами-функциями. И эти понятия здесь трактуются традиционно, как в языках программирования высокого уровня. Хранимая процедура-функция возвращает значение, которое присваивается переменной, определяющей имя процедуры. Процедура в явном виде не возвращает значение, но в ней может быть использовано ключевое слово OUTPUT, которое определяет, что данный параметр является выходным.
Рассмотрим несколько примеров простейших хранимых процедур.
/* процедура проверки наличия экземпляров данной книги
процедура возвращает значение, равное количеству экземпляров
Если возвращается ноль, то это значит, что нет свободных экземпляров данной книги в библиотеке.
CREATE PROCEDURE COUNT_EX (@ISBN varchar(12))
/* определим внутреннюю переменную, которая будет хранить количество экземпляров искомой книги. Количество — это целое число, поэтому наша переменная @ TEK _ COUNT имеет целочисленный тип */
DECLARE @ TEK _ COUNT int
/* выполним соответствующий оператор SELECT
Будем считать только экземпляры, которые в настоящий момент находятся не на руках у читателей, а в библиотеке */
select @TEK_COUNT = count(*) FROM EXEMPLAR WHERE ISBN = @ISBN AND READER_ID Is NULL AND EXIST = True
/* 0 — ноль означает, что нет ни одного свободного экземпляра данной книги в библиотеке */
Мы присвоили возвращаемое значение самой процедуре. Такой способ аналогичен механизму использования функций. Это возможно только в том случае, когда возвращается целое число. Если тип возвращаемого значения иной, то необходимо определить специальным образом возвращаемые, выходные параметры процедуры, которых в общем случае может быть несколько.
9.2. Исполнение хранимых процедур
Поскольку хранимая процедура является полноценным компонентом базы данных, то, как вы уже поняли, создать новую процедуру можно только для текущей базы данных. После создания в системе хранимой процедуры SQL Server компилирует ее и проверяет выполняемые внутри нее операторы. При обнаружении синтаксических ошибок сервер не позволит запустить созданную процедуру на решение. Если вы создаете хранимую процедуру в специальном редакторе внутри Enterprise Manager, то этот редактор не позволит вам сохранить текст процедуры пока в нем есть синтаксические ошибки.
Хранимая процедура может быть вызвана несколькими способами. Простейший способ — это использование оператора:
При этом все входные и выходные параметры должны быть заданы обязательно и в том порядке, в котором они определены в процедуре.
Однако если нам необходимо получить например, число экземпляров книги «Oracle8. Энциклопедия пользователя», которая имеет ISBN 966-7393-08-09, то текст вызова ранее созданной хранимой процедуры может быть следующим:
/*определили две переменные
@Ntek — количество экземпляров данной книги в наличие в библиотеке
@ISBN — международный шифр книги */
DECLARE @ ISBN VARCHAR (14)
/* Присвоим значение переменной @ISBN */
Select @ ISBN = 966-7393-08-09
/* Присвоим переменной @Ntek результаты выполнения хранимой процедуры
EXEC @Ntek = COUNT_EX @ISBN
Если у вас определено несколько версий хранимой процедуры, то при вызове вы можете указать номер конкретной версии для исполнения. Так, например, в версии 2 процедуры COUNT_EX последний оператор исполнения этой процедуры имеет вид:
EXEC @Ntek = COUNT_EX;2 @ISBN
Однако если в процедуре определены значения входных параметров по умолчанию, то при запуске процедуры могут быть указаны значения не всех параметров. В этом случае оператор вызова процедуры может быть записан в следующем виде:
Например, создадим процедуру, которая считает количество книг, изданных конкретным издательством в конкретном году. При создании процедуры зададим для года издания по умолчанию значение текущего года.
CREATE PROCEDURE COUNT_BOOKS (@YEARIZD int = Year(GetDate()),
/* процедура подсчета количества книг конкретного издательства, изданных в конкретом году
@YEARIZD int год издания
@PUBLICH название издательства */
DECLARE @ TEK _ Count int
Select @TEK_count = COUNT(ISBN)
Where YEARIZD = @YEARIZD AND PUBLICH =@PUBLICH
/* одновременно с исполнением оператора Select мы присваиваем результаты его работы определенной ранее переменной @TEK_Count */
При формировании результата работы нашей процедуры мы должны учесть, что в нашей библиотеке, возможно, нет ни одной книги некоторого издательства для заданного года. Результат выполнения запроса SELECT в этом случае будет иметь неопределенное значение, но анализировать все-таки лучше числовые значения. Поэтому в качестве возвращаемого значения мы используем результаты работы специальной встроенной функции Transact SQL COALESCE (n1,n2. nm), которая возвращает первое конкретное, т. е. не равное NULL, значение из списка значений n1,n2. nm. */
Return COALESCE (@ TEK _ Count,0)
Теперь вызовем эту процедуру, для этого подготовим переменную, куда можно поместить результаты выполнения процедуры.
Exec @N = COUNT_BOOKS @PUBLICH = Питер
В переменной @N мы получим количество книг в нашей библиотеке, изданных издательством «Питер» в текущем году. Мы можем обратиться к этой процедуре, задав все параметры:
Exec @N = COUNT_BOOKS @PUBLICH = BHW, @YEARIZD = 2005
Тогда получим количество книг, изданных издательством «BHW» в 2005 г. и присутствующих в нашей библиотеке.
Если мы задаем параметры по именам, то нам необязательно задавать их в том порядке, в котором они описаны при создании процедуры.
В процедурах эффективно могут использоваться операторы ввода данных. Рассмотрим еще один пример — процедуру ввода новой книги. При разработке процедуры совместим не только ввод новой книги, но и ввод данных о всех экземплярах вводимой новой книги.
CREATE PROCEDURE NEW_BOOKS (@ISBN varchar(12),@TITL varchar(255),@YEARIZD int,@PAGES INT,@PUBLISH varchar(30),@NUM_EXEMPL INT)
/* процедура ввода новой книги с указанием количества экземпляров данной книги
Хранимые процедуры в T-SQL — создание, изменение, удаление
В Microsoft SQL Server для реализации и автоматизации своих собственных алгоритмов (расчётов) можно использовать хранимые процедуры, поэтому сегодня мы с Вами поговорим о том, как они создаются, изменяются и удаляются.
Но сначала немного теории, чтобы Вы понимали, что такое хранимые процедуры и для чего они нужны в T-SQL.
Примечание! Начинающим программистам рекомендую следующие полезные материалы на тему T-SQL:
Что такое хранимые процедуры в T-SQL?
Хранимые процедуры – это объекты базы данных, в которых заложен алгоритм в виде набора SQL инструкций. Иными словами, можно сказать, что хранимые процедуры – это программы внутри базы данных. Хранимые процедуры используются для сохранения на сервере повторно используемого кода, например, Вы написали некий алгоритм, последовательный расчет или многошаговую SQL инструкцию, и чтобы каждый раз не выполнять все инструкции, входящие в данный алгоритм, Вы можете оформить его в виде хранимой процедуры. При этом, когда Вы создаете процедуру SQL, сервер компилирует код, а потом, при каждом запуске этой процедуры SQL сервер уже не будет повторно его компилировать.
Для того чтобы запустить хранимую процедуру в SQL Server, необходимо перед ее названием написать команду EXECUTE, также возможно сокращенное написание данной команды EXEC. Вызвать хранимую процедуру в инструкции SELECT, например, как функцию уже не получится, т.е. процедуры запускаются отдельно.
В хранимых процедурах, в отличие от функций, уже можно выполнять операции модификации данных такие как: INSERT, UPDATE, DELETE. Также в процедурах можно использовать SQL инструкции практически любого типа, например, CREATE TABLE для создания таблиц или EXECUTE, т.е. вызов других процедур. Исключение составляет несколько типов инструкций таких как: создание или изменение функций, представлений, триггеров, создание схем и еще несколько других подобных инструкций, например, также нельзя в хранимой процедуре переключать контекст подключения к базе данных (USE).
Хранимая процедура может иметь входные параметры и выходные параметры, она может возвращать табличные данные, может не возвращать ничего, только выполнять заложенные в ней инструкции.
Хранимые процедуры очень полезны, они помогают нам автоматизировать или упростить многие операции, например, Вам постоянно требуется формировать различные сложные аналитические отчеты с использованием сводных таблиц, т.е. оператора PIVOT. Чтобы упростить формирование запросов с этим оператором (как Вы знаете, у PIVOT синтаксис достаточно сложен), Вы можете написать процедуру, которая будет Вам динамически формировать сводные отчеты, например, в материале «Динамический PIVOT в T-SQL» представлен пример реализации данной возможности в виде хранимой процедуры.
Примеры работы с хранимыми процедурами в Microsoft SQL Server
Исходные данные для примеров
Все примеры ниже будут выполнены в Microsoft SQL Server 2016 Express. Для того чтобы продемонстрировать, как работают хранимые процедуры с реальными данными, нам нужны эти данные, давайте их создадим. Например, давайте создадим тестовую таблицу и добавим в нее несколько записей, допустим, что это будет таблица, содержащая список товаров с их ценой.
Данные есть, теперь давайте переходить к созданию хранимых процедур.
Создание хранимой процедуры на T-SQL – инструкция CREATE PROCEDURE
Хранимые процедуры создаются с помощью инструкции CREATE PROCEDURE, после данной инструкции Вы должны написать название Вашей процедуры, затем в случае необходимости в скобочках определить входные и выходные параметры. После этого Вы пишите ключевое слово AS и открываете блок инструкций ключевым словом BEGIN, закрываете данный блок словом END. Внутри данного блока Вы пишите все инструкции, которые реализуют Ваш алгоритм или какой-то последовательный расчет, иными словами, программируете на T-SQL.
Для примера давайте напишем хранимую процедуру, которая будет добавлять новую запись, т.е. новый товар в нашу тестовую таблицу. Для этого мы определим три входящих параметра: @CategoryId – идентификатор категории товара, @ProductName — наименование товара и @Price – цена товара, данный параметр будет у нас необязательный, т.е. его можно будет не передавать в процедуру (например, мы не знаем еще цену), для этого в его определении мы зададим значение по умолчанию. Эти параметры в теле процедуры, т.е. в блоке BEGIN…END можно использовать, так же как и обычные переменные (как Вы знаете, переменные обозначаются знаком @). В случае если Вам нужно указать выходные параметры, то после названия параметра указывайте ключевое слово OUTPUT (или сокращённо OUT).
В блоке BEGIN…END мы напишем инструкцию добавления данных, а также в завершении процедуры инструкцию SELECT, чтобы хранимая процедура вернула нам табличные данные о товарах в указанной категории с учетом нового, только что добавленного товара. Также в этой хранимой процедуре я добавил обработку входящего параметра, а именно удаление лишних пробелов в начале и в конце текстовой строки с целью исключения ситуаций, когда случайно занесли несколько пробелов.
Вот код данной процедуры (его я также прокомментировал).
Запуск хранимой процедуры на T-SQL – команда EXECUTE
Запустить хранимую процедуру, как я уже отмечал, можно с помощью команды EXECUTE или EXEC. Входящие параметры передаются в процедуры путем простого их перечисления и указания соответствующих значений после названия процедуры (для выходных параметров также нужно указывать команду OUTPUT). Однако название параметров можно и не указывать, но в этом случае необходимо соблюдать последовательность указания значений, т.е. указывать значения в том порядке, в котором определены входные параметры (это относится и к выходным параметрам).
Параметры, которые имеют значения по умолчанию, можно и не указывать, это так называемые необязательные параметры.
Вот несколько разных, но эквивалентных способов запуска хранимых процедур, в частности нашей тестовой процедуры.
Изменение хранимой процедуры на T-SQL – инструкция ALTER PROCEDURE
Внести изменения в алгоритм работы процедуры можно с помощью инструкции ALTER PROCEDURE. Иными словами, для того чтобы изменить уже существующую процедуру, Вам достаточно вместо CREATE PROCEDURE написать ALTER PROCEDURE, а все остальное изменять по необходимости.
Допустим, нам необходимо внести изменения в нашу тестовую процедуру, скажем, параметр @Price, т.е. цену, мы сделаем обязательным, для этого уберём значение по умолчанию, а также представим, что у нас пропала необходимость в получении результирующего набора данных, для этого мы просто уберем инструкцию SELECT из хранимой процедуры.
Удаление хранимой процедуры на T-SQL – инструкция DROP PROCEDURE
В случае необходимости можно удалить хранимую процедуру, это делается с помощью инструкции DROP PROCEDURE.
Например, давайте удалим созданную нами тестовую процедуру.
При удалении хранимых процедур стоит помнить о том, что, если на процедуру будут ссылаться другие процедуры или SQL инструкции, после ее удаления они будут завершаться с ошибкой, так как процедуры, на которую они ссылаются, больше нет.
У меня все, надеюсь, материал был Вам интересен и полезен, пока!