Я долго изучал функции и хранимую процедуру, но я не знаю, почему и когда я должен использовать функцию или хранимую процедуру. Они выглядят одинаково для меня, может быть, потому, что я немного новичок в этом.
Может кто-нибудь сказать мне, почему?
Я долго изучал функции и хранимую процедуру, но я не знаю, почему и когда я должен использовать функцию или хранимую процедуру. Они выглядят одинаково для меня, может быть, потому, что я немного новичок в этом.
Может кто-нибудь сказать мне, почему?
Функции являются вычисленными значениями и не могут выполнять постоянные экологические изменения для SQL Server (т.е. Не разрешены инструкции INSERT или UPDATE).
Функция может использоваться inline в операторах SQL, если она возвращает скалярное значение, или может быть объединена, если она возвращает набор результатов.
Необходимо отметить замечания, которые суммируют ответ. Благодаря @Sean K Anderson:
Функции следуют определению компьютерного определения в том, что они ДОЛЖНЫ возвращать значение и не могут изменять данные, которые они получают в качестве параметров (аргументы). Функции не могут ничего менять, должны иметь хотя бы один параметр, и они должны возвращать значение. Сохраненные procs не должны иметь параметр, изменять объекты базы данных и не возвращать значение.
Разница между SP и UDF приведена ниже:
+---------------------------------+----------------------------------------+
| Stored Procedure (SP) | Function (UDF - User Defined |
| | Function) |
+---------------------------------+----------------------------------------+
| SP can return zero , single or | Function must return a single value |
| multiple values. | (which may be a scalar or a table). |
+---------------------------------+----------------------------------------+
| We can use transaction in SP. | We can't use transaction in UDF. |
+---------------------------------+----------------------------------------+
| SP can have input/output | Only input parameter. |
| parameter. | |
+---------------------------------+----------------------------------------+
| We can call function from SP. | We can't call SP from function. |
+---------------------------------+----------------------------------------+
| We can't use SP in SELECT/ | We can use UDF in SELECT/ WHERE/ |
| WHERE/ HAVING statement. | HAVING statement. |
+---------------------------------+----------------------------------------+
| We can use exception handling | We can't use Try-Catch block in UDF. |
| using Try-Catch block in SP. | |
+---------------------------------+----------------------------------------+
Функции и хранимые процедуры служат для отдельных целей. Хотя это не самая лучшая аналогия, функции можно рассматривать буквально как любую другую функцию, которую вы будете использовать на любом языке программирования, но сохраненные procs больше похожи на отдельные программы или пакетные script.
Функции обычно имеют выход и необязательные входы. Затем выход можно использовать как вход для другой функции (встроенный 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
Что происходит, так это то, что функция MyFunction вызывается для каждой строки таблицы MyTable. Если MyTable имеет 1000 строк, то это еще 1000 специальных запросов к базе данных. Аналогично, если функция вызывается, если она задана в спецификации столбца, тогда функция будет вызываться для каждой строки, возвращаемой SELECT.
Таким образом, вам нужно быть осторожными при написании функций. Если вы выполняете SELECT из таблицы в функции, вам нужно спросить себя, можно ли ее лучше выполнять с помощью JOIN в родительском хранимом proc или какой-либо другой конструкции SQL (например, CASE... WHEN... ELSE... END).
Различия между хранимыми процедурами и пользовательскими функциями:
RAISEERROR
ИЛИ @@ERROR
не разрешены в UDF.GETDATE()
не может использоваться в UDF.Напишите пользовательскую функцию, если вы хотите вычислить и вернуть значение для использования в других операторах SQL; пишите хранимую процедуру, когда хотите вместо этого, сгруппировать, возможно, сложный набор операторов SQL. В конце концов, это два довольно разных варианта использования.
STORE PROCEDURE FUNCTION (USER DEFINED FUNCTION)
* Procedure can return 0, single or | * Function can return only single value
multiple values. |
|
* Procedure can have input, output | * Function can have only input
parameters. | parameters.
|
* Procedure cannot be called from | * Functions can be called from
function. | procedure.
|
* Procedure allows select as well as | * Function allows only select statement
DML statement in it. | in it.
|
* Exception can be handled by | * Try-catch block cannot be used in a
try-catch block in a procedure. | function.
|
* We can go for transaction management| * We can't go for transaction
in procedure. | management in function.
|
* Procedure cannot be utilized in a | * Function can be embedded in a select
select statement | statement.
|
* Procedure can affect the state | * Function can not affect the state
of database means it can perform | of database means it can not
CRUD operation on database. | perform CRUD operation on
| database.
|
* Procedure can use temporary tables. | * Function can not use
| temporary tables.
|
* Procedure can alter the server | * Function can not alter the
environment parameters. | environment parameters.
|
* Procedure can use when we want | * Function can use when we want
instead is to group a possibly- | to compute and return a value
complex set of SQL statements. | for use in other SQL
| statements.
Основные отличия
Функция должна возвращать значение, но в Хранимой процедуре это необязательно (процедура может возвращать значения нуля или n).
Функции могут иметь только входные параметры, тогда как процедуры могут иметь параметры ввода/вывода.
Функция принимает один входной параметр, он является обязательным, но хранимая процедура может принимать от n входных параметров.
Функции могут вызываться из процедуры, тогда как процедуры не могут быть вызваны из функции.
Предварительная разница
Процедура позволяет использовать SELECT, а также DML (INSERT/UPDATE/DELETE), тогда как функция разрешает в нем только оператор SELECT.
Процедуры не могут использоваться в инструкции SELECT, тогда как функция может быть встроена в оператор SELECT.
Хранимые процедуры не могут использоваться в операторах SQL в любом месте раздела WHERE/HAVING/SELECT, тогда как функция может быть.
Функции, возвращающие таблицы, можно рассматривать как другой набор строк. Это можно использовать в JOINs с другими таблицами.
Функция Inline может быть, хотя и представлением, которое принимает параметры и может использоваться в JOIN и других операциях Rowset.
Исключение может выполняться блоком try-catch в процедуре, тогда как блок try-catch не может использоваться в функции.
Мы можем пойти для управления транзакциями в процедуре, тогда как мы не можем войти в функцию.
Пользовательская функция является важным инструментом, доступным программисту sql-сервера. Вы можете использовать его inline в SQL-заявлении, например:
SELECT a, lookupValue(b), c FROM customers
где lookupValue
будет UDF. Подобная функциональность невозможна при использовании хранимой процедуры. В то же время вы не можете делать определенные вещи внутри UDF. Основная вещь, которую следует помнить здесь, это то, что UDF's:
хранимая процедура может выполнять эти действия.
Для меня встроенное использование UDF является наиболее важным использованием UDF.
Сохраненные процедуры используются как скрипты. Они запускают ряд команд для вас, и вы можете планировать их запуск в определенное время.
Функции используются как методы. Вы передаете ему что-то, и он возвращает результат. Должно быть маленьким и быстрым - это на лету.
Хранимая процедура:
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 записей, размещенных на сервере на аппаратном уровне среднего класса; в противном случае вам не нужно беспокоиться о поражении производительности, вызванном функциями.
для дальнейшей справки см.: http://databases.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.html
Начните с функций, возвращающих одно значение. Самое приятное, что вы можете поместить часто используемый код в функцию и вернуть их как столбец в результирующем наборе.
Затем вы можете использовать функцию для параметризованного списка городов. dbo.GetCitiesIn( "NY" ) Возвращает таблицу, которая может использоваться как соединение.
Это способ организации кода. Знать, когда что-то многократно используется, и когда это пустая трата времени, это нечто, полученное только путем проб и ошибок и опыта.
Кроме того, функции - хорошая идея в SQL Server. Они быстрее и могут быть достаточно мощными. Встроенный и прямой выбор. Осторожно не злоупотреблять.
Вот практическая причина предпочитать функции над хранимыми процедурами. Если у вас есть хранимая процедура, для которой нужны результаты другой хранимой процедуры, вы должны использовать инструкцию insert-exec. Это означает, что вам нужно создать временную таблицу и использовать оператор exec
, чтобы вставить результаты хранимой процедуры в таблицу temp. Это беспорядочно. Одна из проблем заключается в том, что insert-execs не может быть вложен.
Если вы застряли в хранимых процедурах, которые вызывают другие хранимые процедуры, вы можете столкнуться с этим. Если вложенная хранимая процедура просто возвращает набор данных, ее можно заменить табличной функцией, и вы больше не получите эту ошибку.
(это еще одна причина, по которой мы должны оставить бизнес-логику из базы данных)
Функции могут использоваться в операторе select, где не могут выполняться процедуры.
Сохраненная процедура принимает как входные, так и выходные параметры, но функции принимают только входные параметры.
Функции не могут возвращать значения типа text, ntext, изображения и временных меток, если это возможно.
Функции могут использоваться как пользовательские типы данных в таблице create, но процедуры не могут.
*** Например: -create table <tablename>(name varchar(10),salary getsal(name))
Здесь getal - это определяемая пользователем функция, которая возвращает тип зарплаты, когда таблица создана, для типа зарплаты не выделяется память, а функция getal также не выполняется, но когда мы извлекаем некоторые значения из этой таблицы, функция getal получает выполненный и возвращенный Тип возвращается как результат.
Я понимаю, что это очень старый вопрос, но я не вижу ни одного важного аспекта, упомянутого ни в одном из ответов: включение в план запроса.
Функции могут быть...
Скалярное:
CREATE FUNCTION... RETURNS scalar_type AS BEGIN... END
Многозначный табличный:
CREATE FUNCTION... RETURNS @r TABLE(...) AS BEGIN... END
Встроенное табличное значение:
CREATE FUNCTION... RETURNS TABLE AS RETURN SELECT...
Третий вид (встроенное табличное значение) обрабатывается оптимизатором запросов по существу как (параметризованные) представления, что означает, что ссылка на функцию из вашего запроса аналогична вставке копии тела SQL функции (без фактического вставки копирования), что приводит к к следующим преимуществам:
Вышеуказанное может привести к потенциально значительной экономии производительности, особенно при объединении нескольких уровней функций.
ПРИМЕЧАНИЕ. Похоже, что в SQL Server 2019 также будет введена некоторая форма скалярного встраивания.
Пользовательская функция.
Хранимая процедура
Различия между хранимой процедурой и пользовательской функцией
В SQL Server функции и хранимая процедура представляют собой два разных типа объектов.
Функция: В базе данных SQL Server функции используются для выполнения некоторых действий, и действие немедленно возвращает результат. Функции двух типов:
Определенная система
Пользовательский
Хранимые процедуры:. В SQL Server хранимые процедуры хранятся на сервере и могут возвращать ноль, одно и несколько значений. Хранимые процедуры - это два типа: