хранимая процедура против UDF - PullRequest
1 голос
/ 14 апреля 2010

У меня есть оператор выбора, и в нескольких полях я хочу проверить, существует ли запись для записи в другой таблице и, если это так, вывести 1 значение, а если нет, указать другое значение.

Как лучше всего это сделать? Когда бы вы использовали хранимую процедуру и когда вы использовали бы UDF?

Ответы [ 3 ]

4 голосов
/ 14 апреля 2010

Я бы использовал Left Join.

Select Coalesce(OtherTable.Field, 'Default Value') As Value
From Table
    Left Join OtherTable On Table.OtherTableId = OtherTable.Id
Where Table.Id = @Id
1 голос
/ 14 апреля 2010

Обычно я использую представления, где это возможно, для инкапсуляции низкоуровневой логики и соответствия. Если параметризованное представление (т. Е. Встроенная табличная функция) позволит вам обеспечить выполнение определенных параметров, я бы использовал это. Если необходимо выполнить действие с несколькими операторами, на этом этапе я бы использовал хранимую процедуру.

Преимущества представлений и встроенных табличных функций в том, что оптимизатор может управлять ими намного проще (представления можно комбинировать при построении плана выполнения), а представления и ITVF можно использовать так же, как таблицы, и объединять их с другими таблицами. , просмотры или ITVF практически без затрат по сравнению с повторением встроенного кода.

Например, код в ответе ChaosPandion может быть инкапсулирован в ITVF с использованием параметра (отличный способ гарантировать, что определенные параметры ВСЕГДА предоставляются - нет никакого способа гарантировать, что фильтр критерии будут предоставлены во внешнем SELECT) или в представлении (и параметр должен быть предоставлен вне представления). План выполнения в обоих случаях фактически будет эквивалентен, потому что оптимизатор может очень хорошо обрабатывать подобные случаи.

Наборы результатов хранимых процедур не могут быть объединены без предварительного размещения данных во временной таблице.

CREATE VIEW TableWithDefault
AS
Select Table.Id, Coalesce(OtherTable.Field, 'Default Value') As Value
From Table
    Left Join OtherTable On Table.OtherTableId = OtherTable.Id

-- Usage: SELECT * FROM TableWithDefault WHERE Id = @Id

CREATE FUNCTION TableWithDefault(@Id int)
RETURNS TABLE
RETURN (
    Select Coalesce(OtherTable.Field, 'Default Value') As Value
    From Table
        Left Join OtherTable On Table.OtherTableId = OtherTable.Id
    Where Table.Id = @Id
)

-- Usage: SELECT * FROM TableWithDefault(@Id)

Теперь преимущества этого состоят в том, что эта логика может вызываться из различных хранимых процедур, представлений (OUTER APPLY, CROSS APPLY) и т. Д., И логика всегда находится в одном месте.

0 голосов
/ 14 апреля 2010

Приятной особенностью UDF является то, что вы можете использовать их внутри других запросов. Например, вы можете сказать:

SELECT my_UDF( t.id ) FROM my_table t

Вы также можете использовать UDF как таблицу:

SELECT * FROM my_udf() t

Так что, если вы считаете, что ваш запрос содержит некоторую логику общего назначения, которая может использоваться в нескольких запросах в вашем приложении / базе данных, вы можете рассмотреть возможность использования UDF. Но есть некоторые ограничения. Например, UDF не может вызывать недетерминированные встроенные функции, такие как GETDATE. Таким образом, вам нужно будет использовать хранимую процедуру для работы с этими функциями. Для получения дополнительной информации см .: Разница между пользовательской функцией и хранимой процедурой .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...