Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este tópico descreve como criar uma função definida pelo usuário no SQL Server usando o Transact-SQL.
Nesse Tópico
Antes de começar:
Para criar uma função definida pelo usuário:
Antes de começar
Limitações e restrições
As funções definidas pelo usuário não podem ser usadas para executar ações que modifiquem o estado do banco de dados.
As funções definidas pelo usuário não podem conter uma cláusula OUTPUT INTO que tenha uma tabela como destino.
As funções definidas pelo usuário não podem retornar vários conjuntos de resultados. Use um procedimento armazenado se precisar retornar vários conjuntos de resultados.
O tratamento de erros é restrito em uma função definida pelo usuário. Uma UDF não dá suporte a TRY...CATCH, @ERROR ou RAISERROR.
As funções definidas pelo usuário não podem chamar um procedimento armazenado, mas podem chamar um procedimento armazenado estendido.
As funções definidas pelo usuário não podem usar tabelas temporárias ou SQL dinâmicas. Variáveis de tabela são permitidas.
Instruções SET não são permitidas em uma função definida pelo usuário.
A cláusula FOR XML não é permitida
As funções definidas pelo usuário podem ser aninhadas; ou seja, uma função definida pelo usuário pode chamar outra. O nível de aninhamento é incrementado quando a função chamada inicia a execução e decrementado quando a função chamada termina a execução. As funções definidas pelo usuário podem ser aninhadas até 32 níveis. Exceder os níveis máximos de aninhamento faz com que toda a cadeia de funções de chamada falhe. Qualquer referência ao código gerenciado de uma função definida pelo usuário Transact-SQL conta como um nível em relação ao limite de aninhamento de 32 níveis. Os métodos invocados de dentro do código gerenciado não contam com esse limite.
As seguintes instruções do Service Broker não podem ser incluídas na definição de uma função definida pelo usuário Transact-SQL:
INICIAR CONVERSA DE DIÁLOGO
ENCERRAR CONVERSAÇÃO
OBTER GRUPO DE CONVERSAÇÃO
Transferir Conversa
RECEBER
ENVIAR
Segurança
Permissões
Requer a permissão CREATE FUNCTION no banco de dados e a permissão ALTER no esquema no qual a função está sendo criada. Se a função especificar um tipo definido pelo usuário, exigirá a permissão EXECUTE no tipo.
Funções escalares
O exemplo a seguir cria uma função escalar de vários estados no banco de dados AdventureWorks2012. A função usa um valor de entrada, um ProductIDe retorna um único valor de dados, a quantidade agregada do produto especificado no inventário.
IF OBJECT_ID (N'dbo.ufnGetInventoryStock', N'FN') IS NOT NULL
DROP FUNCTION ufnGetInventoryStock;
GO
CREATE FUNCTION dbo.ufnGetInventoryStock(@ProductID int)
RETURNS int
AS
-- Returns the stock level for the product.
BEGIN
DECLARE @ret int;
SELECT @ret = SUM(p.Quantity)
FROM Production.ProductInventory p
WHERE p.ProductID = @ProductID
AND p.LocationID = '6';
IF (@ret IS NULL)
SET @ret = 0;
RETURN @ret;
END;
GO
O exemplo a seguir usa a ufnGetInventoryStock função para retornar a quantidade de inventário atual para produtos que têm ProductModelID entre 75 e 80.
SELECT ProductModelID, Name, dbo.ufnGetInventoryStock(ProductID)AS CurrentSupply
FROM Production.Product
WHERE ProductModelID BETWEEN 75 and 80;
Table-Valued Funções
O exemplo a seguir cria uma função embutida com valor de tabela no banco de dados AdventureWorks2012. A função usa um parâmetro de entrada, uma ID do cliente (loja), e retorna as colunas ProductID, Name, e a agregação de vendas acumuladas no ano como YTD Total para cada produto vendido para a loja.
IF OBJECT_ID (N'Sales.ufn_SalesByStore', N'IF') IS NOT NULL
DROP FUNCTION Sales.ufn_SalesByStore;
GO
CREATE FUNCTION Sales.ufn_SalesByStore (@storeid int)
RETURNS TABLE
AS
RETURN
(
SELECT P.ProductID, P.Name, SUM(SD.LineTotal) AS 'Total'
FROM Production.Product AS P
JOIN Sales.SalesOrderDetail AS SD ON SD.ProductID = P.ProductID
JOIN Sales.SalesOrderHeader AS SH ON SH.SalesOrderID = SD.SalesOrderID
JOIN Sales.Customer AS C ON SH.CustomerID = C.CustomerID
WHERE C.StoreID = @storeid
GROUP BY P.ProductID, P.Name
);
O exemplo a seguir invoca a função e especifica a ID do cliente 602.
SELECT * FROM Sales.ufn_SalesByStore (602);
O exemplo a seguir cria uma função com valor de tabela no banco de dados AdventureWorks2012. A função usa um único parâmetro de entrada, um EmployeeID e retorna uma lista de todos os funcionários que se reportam ao funcionário especificado direta ou indiretamente. Em seguida, a função é invocada especificando a ID 109 do funcionário.
IF OBJECT_ID (N'dbo.ufn_FindReports', N'TF') IS NOT NULL
DROP FUNCTION dbo.ufn_FindReports;
GO
CREATE FUNCTION dbo.ufn_FindReports (@InEmpID INTEGER)
RETURNS @retFindReports TABLE
(
EmployeeID int primary key NOT NULL,
FirstName nvarchar(255) NOT NULL,
LastName nvarchar(255) NOT NULL,
JobTitle nvarchar(50) NOT NULL,
RecursionLevel int NOT NULL
)
--Returns a result set that lists all the employees who report to the
--specific employee directly or indirectly.*/
AS
BEGIN
WITH EMP_cte(EmployeeID, OrganizationNode, FirstName, LastName, JobTitle, RecursionLevel) -- CTE name and columns
AS (
SELECT e.BusinessEntityID, e.OrganizationNode, p.FirstName, p.LastName, e.JobTitle, 0 -- Get the initial list of Employees for Manager n
FROM HumanResources.Employee e
INNER JOIN Person.Person p
ON p.BusinessEntityID = e.BusinessEntityID
WHERE e.BusinessEntityID = @InEmpID
UNION ALL
SELECT e.BusinessEntityID, e.OrganizationNode, p.FirstName, p.LastName, e.JobTitle, RecursionLevel + 1 -- Join recursive member to anchor
FROM HumanResources.Employee e
INNER JOIN EMP_cte
ON e.OrganizationNode.GetAncestor(1) = EMP_cte.OrganizationNode
INNER JOIN Person.Person p
ON p.BusinessEntityID = e.BusinessEntityID
)
-- copy the required columns to the result of the function
INSERT @retFindReports
SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel
FROM EMP_cte
RETURN
END;
GO
-- Example invocation
SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel
FROM dbo.ufn_FindReports(1);
Consulte Também
Funções definidas pelo usuário
CREATE FUNCTION (Transact-SQL)