Зачем нужны пользовательские функции в SQL Server?
Какова точная потребность в пользовательских функциях в SQL Server?
Все, что мы можем сделать с помощью функций, может быть выполнено с помощью хранимых процедур, так почему же были введены пользовательские функции?
Я знаю о различиях между хранимыми процедурами и функциями, но ни одна из них не проясняет мой вопрос, и я не смог найти ничего, что функция может сделать, чего не могут хранимые процедуры.
Функции только для удобства обслуживания и понимания или я что-то упустил?
2 ответа
Все, что мы можем сделать, используя функции, может быть сделано самими хранимыми процедурами,
Это неверно
- Хранимые процедуры не могут быть перекомпонованы или встроены (например, как
VIEW
или табличная функция может - и SQL Server 2017 теперь может также включать скалярные функции). - Хранимые процедуры не могут быть доказаны "безопасными" механизмом базы данных (поскольку хранимые процедуры могут выполнять операции DML/DDL, тогда как пользовательские функции могут выполнять только операции только для чтения).
- Хранимые процедуры не могут использоваться для выполнения операций над скалярными значениями.
Вы можете утверждать, что все, что вы можете сделать внутри запроса, который будет использовать UDF, может быть сделано без этого UDF - и это технически верно (потому что хранимые процедуры завершены по Тьюрингу), но это все равно что сказать, что нам не нужно for
, while
, try/catch
, using
, или же async
в C#, потому что, конечно, if
а также goto
это достаточно хорошо для всех!
Качество кода, удобство сопровождения и производительность во время выполнения имеют значение - правильное использование пользовательских функций приводит не только к эстетически красивым запросам, но и к лучшей производительности благодаря встраиванию, перекомпоновке, сокращению дерева выражений и так далее.
Кроме того, кто сегодня использует хранимые процедуры, когда все классные дети используют Entity Framework?:D
сноска
Я хочу уточнить мое замечание:
Хранимые процедуры не могут использоваться для выполнения операций над скалярными значениями.
Несмотря на то, что хранимые процедуры имеют возвращаемые значения и выходные параметры, они не классифицируются так же, как истинные UDF, поскольку возвращаемое значение хранимой процедуры может быть только int
значение (они ближе к программным кодам завершения в POSIX/Win32, чем к реальному возвращаемому значению) и выходные параметры хранимой процедуры не могут использоваться внутри другого запроса, если вы не делаете некрасивые хаки с CURSOR
или динамический SQL (инъекция).
В дополнение ко всем пунктам, которые @Dai уже упомянул: я использовал скалярные функции для "извлечения" определенных битов в виде атомарных значений (например, INT
и т.д.) из довольно большого столбца XML и использовал скалярную функцию для определения вычисляемого столбца (на основе этого столбца XML).
Это еще одна вещь, которую вы НЕ МОЖЕТЕ сделать с хранимой процедурой - используйте функцию, чтобы определить значение вычисляемого столбца (или определить проверку или ограничение по умолчанию для "обычного" столбца).