[sql-function] Функция против хранимой процедуры в SQL Server. Процедуры в sql
[sql-function] Функция против хранимой процедуры в SQL Server [stored-procedures] [tsql]
Функции являются вычисленными значениями и не могут выполнять постоянные экологические изменения для SQL Server (т. Е. Не разрешены инструкции INSERT или UPDATE).
Функция может использоваться inline в операторах SQL, если она возвращает скалярное значение, или может быть объединена, если она возвращает набор результатов.
Необходимо отметить замечания, которые суммируют ответ. Благодаря @Sean K Anderson:
Функции следуют определению компьютерного определения в том, что они ДОЛЖНЫ возвращать значение и не могут изменять данные, которые они получают в качестве параметров (аргументы). Функции не могут ничего менять, должны иметь хотя бы один параметр, и они должны возвращать значение. Сохраненные procs не должны иметь параметр, изменять объекты базы данных и не возвращать значение.
Функции и хранимые процедуры служат отдельным целям. Хотя это не лучшая аналогия, функции можно рассматривать буквально как любую другую функцию, которую вы будете использовать на любом языке программирования, но сохраненные procs больше похожи на отдельные программы или пакетный скрипт.
Обычно функции имеют выходные и опциональные входы. Затем вывод можно использовать как вход для другой функции (встроенный SQL Server, такой как DATEDIFF, LEN и т. Д.) Или как предикат SQL Query - например, SELECT a, b, dbo.MyFunction(c) FROM table или SELECT a, b, c FROM table WHERE a = dbo.MyFunc(c) .
Сохраненные procs используются для связывания SQL-запросов вместе в транзакции и взаимодействия с внешним миром. Такие структуры, как ADO.NET и т. Д., Не могут вызывать функцию напрямую, но они могут напрямую вызвать хранимый процесс.
У функций есть скрытая опасность: они могут быть неправильно использованы и вызывать довольно неприятные проблемы с производительностью: рассмотрите этот запрос:
SELECT * FROM dbo.MyTable WHERE col1 = dbo.MyFunction(col2)Где MyFunction объявлен как:
CREATE FUNCTION MyFunction (@someValue INTEGER) RETURNS INTEGER AS BEGIN DECLARE @retval INTEGER SELECT localValue FROM dbo.localToNationalMapTable WHERE nationalValue = @someValue RETURN @retval ENDТаким образом, вам нужно быть осторожными при написании функций. Если вы выполняете SELECT из таблицы в функции, вам нужно спросить себя, можно ли ее лучше выполнять с помощью JOIN в родительском хранимом proc или какой-либо другой конструкции SQL (например, CASE ... WHEN ... ELSE ... КОНЕЦ).
Различия между хранимыми процедурами и пользовательскими функциями:
- Сохраненные процедуры не могут использоваться в операторах Select.
- Сохраненные процедуры поддерживают разрешение отложенного имени.
- Хранимые процедуры обычно используются для выполнения бизнес-логики.
- Хранимые процедуры могут возвращать любой тип данных.
- Хранимые процедуры могут принимать большее количество входных параметров, чем определенные пользователем функции. Сохраненные процедуры могут содержать до 21 000 входных параметров.
- Хранимые процедуры могут выполнять Dynamic SQL.
- Хранимые процедуры поддерживают обработку ошибок.
- Недетерминированные функции могут использоваться в хранимых процедурах.
- Пользовательские функции могут использоваться в операторах Select.
- Пользовательские функции не поддерживают разрешение отложенного имени.
- Пользовательские функции обычно используются для вычислений.
- Пользовательские функции должны возвращать значение.
- Пользовательские функции не могут возвращать изображения.
- Пользовательские функции принимают меньшее количество входных параметров, чем хранимые процедуры. UDF могут иметь до 1 023 входных параметров.
- Временные таблицы не могут использоваться в пользовательских функциях.
- Пользовательские функции не могут выполнять Dynamic SQL.
- Пользовательские функции не поддерживают обработку ошибок. RAISEERROR ИЛИ @@ERROR не разрешены в UDF.
- Недетерминированные функции не могут использоваться в UDF. Например, GETDATE() не может использоваться в UDF.
Основные отличия
Функция должна возвращать значение, но в Хранимой процедуре это необязательно (процедура может возвращать значения нуля или n).
Функции могут иметь только входные параметры, тогда как процедуры могут иметь параметры ввода / вывода.
Функция принимает один входной параметр, он является обязательным, но хранимая процедура может принимать значения от n входных параметров.
Функции можно вызывать из процедуры, тогда как процедуры не могут быть вызваны из функции.
Предварительная разница
Процедура позволяет использовать SELECT, а также DML (INSERT / UPDATE / DELETE), тогда как функция разрешает в нем только оператор SELECT.
Процедуры не могут использоваться в инструкции SELECT, тогда как функция может быть встроена в инструкцию SELECT.
Хранимые процедуры не могут использоваться в операторах SQL в любом месте раздела WHERE / HAVING / SELECT, тогда как функция может быть.
Функции, возвращающие таблицы, можно рассматривать как другой набор строк. Это можно использовать в JOINs с другими таблицами.
Встроенная функция может быть, хотя и представлением, которое принимает параметры и может использоваться в JOIN и других операциях Rowset.
Исключение может быть обработано блоком try-catch в процедуре, тогда как блок try-catch не может использоваться в функции.
Мы можем пойти для управления транзакциями в процедуре, тогда как мы не можем войти в функцию.
source
Хранимая процедура:
- Является миниатюрной программой в SQL Server.
- Может быть так же просто, как оператор select или сложный, как длинный скрипт, который добавляет, удаляет, обновляет и / или считывает данные из нескольких таблиц в базе данных.
- (Может реализовывать циклы и курсоры, которые позволяют работать с меньшими результатами или по строковым операциям с данными).
- Должен вызываться с использованием инструкции EXEC или EXECUTE .
- Возвращает переменные таблицы, но мы не можем использовать параметр OUT .
- Поддерживает транзакции.
Функция:
- Не может использоваться для обновления, удаления или добавления записей в базу данных.
- Просто возвращает одно значение или значение таблицы.
Может использоваться только для выбора записей. Однако его можно легко вызвать из стандартного SQL, например:
SELECT dbo.functionname('Parameter1')или SELECT Name, dbo.Functionname('Parameter1') FROM sysObjectsДля простых операций многократного выбора функции могут упростить код. Просто будьте осторожны с использованием предложений JOIN в ваших функциях. Если ваша функция имеет предложение JOIN , и вы вызываете ее из другого оператора select, который возвращает несколько результатов, этот вызов функции будет JOIN эти таблицы вместе для каждой строки, возвращенной в результирующем наборе. Поэтому, хотя они могут помочь в упрощении некоторой логики, они также могут быть узким местом производительности, если они не используются должным образом.
- Возвращает значения с использованием параметра OUT .
- Не поддерживает транзакции.
Функции SQL Server, такие как курсоры, предназначены для использования в качестве вашего последнего оружия! У них есть проблемы с производительностью, поэтому следует избегать как можно большего использования табличной функции. Говоря о производительности, речь идет о таблице с более чем 1 000 000 записей, размещенных на сервере на аппаратном уровне среднего класса; в противном случае вам не нужно беспокоиться о поражении производительности, вызванном функциями.
- Никогда не используйте функцию для возврата результата к внешнему коду (например, ADO.Net)
- Используйте максимально возможную комбинацию представлений / сохраненных процедур. вы можете оправиться от будущих проблем роста производительности, используя предложения, которые DTA (Database Tuning Adviser) предоставит вам (например, индексированные представления и статистику) - иногда!
для дальнейшей справки см .: http://databases.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.html
- Для функции обязательно возвращать значение, если оно не для хранимой процедуры.
- Выбирать утверждения, принимаемые только в UDF, тогда как инструкции DML не требуются.
- Хранимая процедура принимает любые утверждения, а также заявления DML.
- UDF позволяет только входы, а не выходы.
- Сохраненная процедура позволяет использовать как входы, так и выходы.
- Блоки уловов не могут использоваться в UDF, но могут использоваться в хранимой процедуре.
- Никаких транзакций, разрешенных в функциях в UDF, а в хранимой процедуре они разрешены.
- В UDF могут использоваться только табличные переменные, а не временные таблицы.
- Хранимая процедура позволяет использовать как переменные таблицы, так и временные таблицы.
- UDF не позволяет вызывать хранимые процедуры из функций, в то время как хранимые процедуры позволяют вызывать функции.
- UDF используется в предложении join, в то время как хранимые процедуры не могут использоваться в предложении join.
- Хранимая процедура всегда позволяет вернуть к нулю. UDF, напротив, имеет значения, которые должны возвращаться в заданную точку.
Вот практическая причина предпочитать функции над хранимыми процедурами. Если у вас есть хранимая процедура, для которой нужны результаты другой хранимой процедуры, вы должны использовать инструкцию insert-exec. Это означает, что вам нужно создать временную таблицу и использовать инструкцию exec для вставки результатов хранимой процедуры в таблицу temp. Это грязно. Одна из проблем заключается в том, что insert-execs не может быть вложенным .
Если вы застряли в хранимых процедурах, которые вызывают другие хранимые процедуры, вы можете столкнуться с этим. Если вложенная хранимая процедура просто возвращает набор данных, ее можно заменить табличной функцией, и вы больше не получите эту ошибку.
( это еще одна причина, по которой мы должны оставить бизнес-логику из базы данных )
code-examples.net
Создание хранимых процедур в mysql
Определение 1
Хранимая процедура – это самостоятельная часть программного код, которую создают и хранят в БД MySQL.
В состав хранимой процедуры могут входить SQL-операторы и специальные управляющие структуры. Удобна в использовании, если одну и ту же функцию нужно выполнить из разных приложений или с разных платформ, или в качестве средства сокрытия функциональных возможностей. В базе данных хранимые процедуры считаются аналогом объектно-ориентированного подхода в программировании. С помощью хранимых процедур можно управлять способом доступа к данным.
Создание хранимой процедуры
Создадим процедуру с именем GetAllProducts() для получения списка всех продуктов из таблицы.
Для этого нужно загрузить mysql-клиент и выполнить следующие команды:
Команда DELIMITER // не входит в хранимые процедуры. DELIMITER – специальная команда, изменяющая стандартный разделитель запросов (по умолчанию «;») на указанный после нее. Этой командой изменим его на 2 слеша (//).
Если не изменить разделитель, то mysql ошибочно интерпретирует процедуру и выдаст ошибку. После END используется разделитель // и с помощью команды DELIMITER возвращается значение разделителя «;».
Зарезервированные слова CREATE PROCEDURE указывают mysql, что нужно СОЗДАТЬ ПРОЦЕДУРУ. После этих слов нужно указать название хранимой процедуры (в примере GetAllProducts). Пустые скобки «()» после названия процедуры означает, что процедура не принимает никаких переменных.
Команды BEGIN и END соответственно открывают и закрывают блок кода SQL.
В консоли mysql хранимые процедуры писать не очень удобно. В таком случае можно воспользоваться GUI tools, с помощью которых можно создавать хранимые процедуры в интуитивно понятном интерфейсе.
В MySQL Workbench процедура создается нажатием правой кнопкой мыши на Routines и выбором в выпадающем меню пункта Create Procedure…
Далее вводим название хранимой процедуры и нажимаем кнопку Apply.
Можно просмотреть полный код, который отправится в MySQL, перед тем, как он запишется в базу данных. Если ошибок нет, нажимаем Apply.
После компиляции MySQL записывает процедуру в каталог. После завершения записи нажимаем кнопку Finish.
Можно увидеть созданную хранимую процедуру в списке Routines.
Вызов хранимой процедуры
Для вызова хранимой процедуры используется встроенная SQL команда CALL (ВЫЗВАТЬ):
Вместо STORED_PROCEDURE_NAME указывается имя хранимой процедуры, а в скобках указывается список переменных. Для вызова созданной процедуры без переменных будет использоваться код:
Т.к. процедура должна выполнять команду *SELECT FROM products;**, т.е. ВЫБРАТЬ все ИЗ таблицы ПРОДУКТЫ, то примером ее работы может быть следующий результат:
Переменные в хранимых процедурах
Определение 2
Переменная является именованным объектом данных, содержащим некоторое значение при выполнении хранимой процедуры.
Их используют для сохранения какого-либо результата запроса или выражения. Переменные в хранимых процедурах являются локальными, т.е. их нельзя вызвать извне.
Декларирование переменных
Определение 3
Процесс сообщения mysql о том, что нужно использовать переменную, называют декларированием.
Для декларирования переменных используется оператор DECLARE:
DECLARE – зарезервированный оператор.
variable_name – название переменной, к которому применяют такие же правила, что и к названию столбца данных в MySQL.
datatype(size) – тип переменной, которая используется, и ее размер. Переменные в MySQL могут принимать значения любого типа данных, например DATETIME, VARCHAR, INT и др.
DEFAULT default_value – позволяет задавать начальное значение переменной. Если оно не задано, то будет установлено значение по умолчанию NULL.
Для создания переменной total_sale, в которой будет храниться список покупок типа INT, и которая по умолчанию будет равна 0, запишем код:
Для декларирования нескольких переменных одного типа можно записать код:
или:
Присвоение значений переменной
Для присвоения значения переменной используют оператор SET.
К примеру, декларируем переменную total_count, а затем присвоим ей значение 10:
Помимо оператора SET может использоваться оператор SELECT INTO для передачи результата запроса в переменную. Обратим внимание, что запрос должен вернуть скалярное значение (т.е. одно).
В первой строке кода объявляется переменная total_products и устанавливается ее значение в 0.
Во второй и третьей строке используется оператор SELECT INTO для записи результата выполнения запроса SELECT COUNT(*) FROM products в созданную переменную.
Область видимости переменных
Каждая переменная имеет свою область видимости, определяющую время ее жизни.
Если создать переменную внутри хранимой процедуры, то она будет существовать, пока используется.
Если декларировать переменную внутри блока BEGIN END, то она будет существовать лишь в пределах этого блока.
Переменные со знаком @ вначале названия являются глобальными, т.е. они являются доступными на протяжении всей сессии.
spravochnick.ru
sql - Вставка результатов хранимой процедуры во временную таблицу
Quassnoi поместил меня большую часть пути, но ничего не было:
**** Мне нужно было использовать параметры в хранимой процедуре. ****
И OPENQUERY не позволяет это произойти:
Итак, я нашел способ работать с системой, а также не должен делать определение таблицы таким жестким и переопределять его в другой хранимой процедуре (и, конечно, риск, что она может сломаться)!
Да, вы можете динамически создать определение таблицы, возвращенное из хранимой процедуры, используя оператор OPENQUERY с фиктивными переменными (поскольку NO RESULT SET возвращает то же количество полей и в том же положении, что и набор данных с хорошими данными).
После создания таблицы вы можете использовать хранимую процедуру exec во временной таблице в течение всего дня.
И чтобы отметить (как указано выше), вы должны включить доступ к данным,
EXEC sp_serveroption 'MYSERVERNAME', 'DATA ACCESS', TRUEкод:
declare @locCompanyId varchar(8) declare @locDateOne datetime declare @locDateTwo datetime set @locDateOne = '2/11/2010' set @locDateTwo = getdate() --Build temporary table (based on bogus variable values) --because we just want the table definition and --since openquery does not allow variable definitions... --I am going to use bogus variables to get the table defintion. select * into #tempCoAttendanceRpt20100211 FROM OPENQUERY(DBASESERVER, 'EXEC DATABASE.dbo.Proc_MyStoredProc 1,"2/1/2010","2/15/2010 3:00 pm"') set @locCompanyId = '7753231' insert into #tempCoAttendanceRpt20100211 EXEC DATABASE.dbo.Proc_MyStoredProc @locCompanyId,@locDateOne,@locDateTwo set @locCompanyId = '9872231' insert into #tempCoAttendanceRpt20100211 EXEC DATABASE.dbo.Proc_MyStoredProc @locCompanyId,@locDateOne,@locDateTwo select * from #tempCoAttendanceRpt20100211 drop table #tempCoAttendanceRpt20100211Спасибо за информацию, которая была предоставлена изначально... Да, наконец, мне не нужно создавать все эти фальшивые (строгие) таблицы при использовании данных из другой хранимой процедуры или базы данных и да, вы также можете использовать параметры.
Поиск ссылочных тегов:
-
Хранимая процедура SQL 2005 в таблицу temp
-
openquery с хранимой процедурой и переменными 2005
-
openquery с переменными
-
выполнить хранимую процедуру в таблице temp
Обновление: это не будет работать с временными таблицами, поэтому мне пришлось прибегать к ручному созданию временной таблицы.
Замечание Bummer: это не будет работать с временными таблицами, http://www.sommarskog.se/share_data.html#OPENQUERY
Ссылка: Следующее - определить LOCALSERVER. Он может выглядеть как ключевое слово в примере, но на самом деле это только имя. Вот как вы это делаете:
sp_addlinkedserver @server = 'LOCALSERVER', @srvproduct = '', @provider = 'SQLOLEDB', @datasrc = @@servernameЧтобы создать связанный сервер, вы должны иметь разрешение ALTER ANY SERVER или быть членом любой из фиксированных ролей сервера sysadmin или setupadmin.
OPENQUERY открывает новое подключение к SQL Server. Это имеет некоторые последствия:
Процедура, которую вы вызываете с помощью OPENQUERY, не может ссылаться на временные таблицы, созданные в текущем соединении.
Новое соединение имеет свою собственную базу данных по умолчанию (определенную с помощью sp_addlinkedserver, по умолчанию - master), поэтому вся спецификация объекта должна содержать имя базы данных.
Если вы открыли транзакцию и удерживаете блокировки при вызове OPENQUERY, вызываемая процедура не может получить доступ к заблокированному. То есть, если вы не будете осторожны, вы заблокируете себя.
Подключение осуществляется не бесплатно, поэтому есть ограничение производительности.
qaru.site
Хранимые процедуры в среде MS SQL Server
Хранимые процедуры являются полноценными объектами базы данных, а потому каждая из них хранится в конкретной базе данных.
Непосредственный вызов хранимой процедуры возможен, только если он осуществляется при использовании той базы данных, в которой находится процедура.
Типы хранимых процедур
В SQL Server имеется несколько типов хранимых процедур.
Системные хранимые процедурыпредназначены для выполнения различных административных действий. Практически все действия по администрированию сервера выполняются с их помощью.
Можно сказать, что системные хранимые процедуры являются интерфейсом, обеспечивающим работу с системными таблицами, которая, в конечном счете, сводится к изменению, добавлению, удалению и выборке данных из системных таблиц как пользовательских, так и системных баз данных.
Системные хранимые процедуры имеют префикс sp_ , хранятся в системной базе данных и могут быть вызваны при использовании любой другой базы данных.
Пользовательские хранимые процедурыреализуют те или иные действия. Хранимые процедуры - полноценный объект базы данных. Они располагаются в конкретной базе данных, где и выполняются.
Временные хранимые процедурысуществуют лишь некоторое время, после чего автоматически уничтожаются сервером. Они делятся на две категории:
1. локальные;
2. глобальные.
Локальные временные хранимые процедурымогут быть вызваны только из того соединения, в котором созданы.
При создании такой процедуры ей необходимо дать имя, начинающееся с одного символа #.
Как и все временные объекты, хранимые процедуры этого типа автоматически удаляются при отключении пользователя, перезапуске или остановке сервера.
Глобальные временные хранимые процедурыдоступны для любых существующих в данный момент соединений сервера, на которых имеется такая же процедура.
Для ее определения достаточно дать ей имя, начинающееся с символов ##.
Удаляются эти процедуры при перезапуске или остановке сервера, а также при закрытии соединения, в котором которого они были созданы.
Создание, изменение и удаление хранимых процедур
Создание хранимой процедуры предполагает решение следующих
задач:
1. определение типа создаваемой хранимой процедуры: пользовательская или временная. Можно создать свою собственную системную хранимую процедуру, назначив ей имя с префиксом sp_и поместив ее в системную базу данных. Такая процедура будет доступна в контексте любой базы данных локального сервера;
2. планирование прав доступа. При создании хранимой процедуры следует учитывать, что она будет иметь те же права доступа к объектам базы данных, что и создавший ее пользователь;
3. определение параметров хранимой процедуры. Подобно процедурам, входящим в состав большинства языков программирования, хранимые процедуры могут обладать входными и выходными параметрами;
4. разработка кода хранимой процедуры. Код процедуры может содержать последовательность любых команд SQL, включая вызов других хранимых процедур.
Создание новой и изменение имеющейся хранимой процедуры осуществляется с помощью следующей команды:
<определение_процедуры>::=
{CREATE | ALTER} PROC [EDURE ] имя_процедуры [; номер]
[(@имя_параметра тип_данных ] [VARYING] [= default]
[OUTPUT ] ] [,...n]
[ READONLY ]
[WITH{ RECOMPILE| ENCRYPTION}]
[FOR REPLICATION ]
AS
SQL_onepaтоpы [ ...n]
Рассмотрим параметры данной команды.
Используя префиксы sp_, #, ##, создаваемую процедуру можно определить в качестве системной или временной.
Как видно из синтаксиса команды, не допускается указывать имя владельца, которому будет принадлежать создаваемая процедура, а также имя базы данных, где она должна быть размещена.
Таким образом, чтобы разместить создаваемую хранимую процедуру в конкретной базе данных, необходимо выполнить команду
CREATE PROCEDUREпри использовании этой базы данных.
При обращении из тела хранимой процедуры к объектам той же базы данных можно использовать укороченные имена, т. е. без указания имени базы данных. Когда же требуется обратиться к объектам, расположенным в других базах данных, указание имени базы данных обязательно.
Для удобства управления процедурами логически однотипные хранимые процедуры можно группировать, присваивая им одинаковые имена, но разные идентификационные номера, то есть создавать группу процедур.
Номер в имени - это идентификационный номер хранимой процедуры, однозначно определяющий ее в группе процедур (если создается группа).
Для передачи входных и выходных данных в создаваемой хранимой процедуре могут использоваться параметры, имена которых, как и имена локальных переменных, должны начинаться с символа @.
В одной хранимой процедуре можно задать множество параметров, разделенных запятыми.
В теле процедуры нельзя применять локальные переменные, чьи имена совпадают с именами параметров этой процедуры.
Для определения типа данных, который будет иметь соответствующий параметр хранимой процедуры, годятся любые типы данных SQL, включая определенные пользователем. Однако тип данных CURSORможет быть использован только как выходной параметр хранимой процедуры, т.е. с указанием ключевого слова OUTPUT .
Наличие ключевого слова OUTPUT означает, что соответствующий параметр предназначен для возвращения данных из хранимой процедуры. Однако это вовсе не означает, что этот параметр не подходит и для передачи значений в хранимую процедуру.
Указание ключевого слова OUTPUTпредписывает серверу при выходе из хранимой процедуры присвоить текущее значение параметра локальной переменной, которая была указана при вызове процедуры в качестве значения параметра.
Отметим, что при указании ключевого слова OUTPUT значение соответствующего параметра при вызове процедуры может быть задано только с помощью локальной переменной.
Не разрешается использование любых выражений или констант, допустимое для обычных параметров.
Ключевое слово VARYINGприменяется совместно с параметром
OUTPUT , имеющим тип CURSOR . Оно определяет, что выходным параметром будет некоторое результирующее множество.
Ключевое слово DEFAULTпредставляет собой значение, которое будет принимать соответствующий параметр по умолчанию. В этом случае при вызове процедуры можно не указывать явно значение соответствующего параметра.
Так как сервер кэширует план исполнения запроса и откомпилированный код, при последующем вызове процедуры будут использоваться уже готовые значения. Однако в некоторых случаях все же требуется выполнять перекомпиляцию кода процедуры. Указание ключевого слова RECOMPILE предписывает системе создавать новый план выполнения хранимой процедуры при каждом ее вызове.
Параметр FOR REPLICATIONвостребован при репликации данных и включении создаваемой хранимой процедуры в качестве статьи в публикацию,
Ключевое слово encryptionпредписывает серверу выполнить шифрование кода хранимой процедуры, что может обеспечить защиту от использования авторских алгоритмов, реализующих работу хранимой процедуры.
Ключевое слово ASразмещается в начале собственно тела хранимой процедуры, т.е. набора команд SQL, с помощью которых и будет реализовываться то или иное действие. В теле процедуры могут применяться практически все команды SQL, объявляться транзакции, устанавливаться блокировки и вызываться другие хранимые процедуры.
Выход из хранимой процедуры можно осуществить посредством команды RETURN .
Удаление хранимой процедуры осуществляется командой :
DROP PROCEDURE{имя_процедуры> [,...n]}
studlib.info