Desvendando o SQL - Parte X - Funções
Autor: Rubens Lima | Publicado: 2013-08-16T09:33:00-03:00





Estamos novamente aqui com vocês,
hoje pra falar de mais um assunto da linguagem SQL que são as FUNCTIONS ou
Funções. No artigo passado falamos sobre Procedures, as FUNCTIONS são bem
parecidas, pois também podem realizar alguns processos, receber parâmetros, com
uma diferença, as funções devolvem um resultado. 




Utilização



Podemos utilizá-las para criar
rotinas reutilizáveis das maneiras abaixo:





Em instruções Transact-SQL, como SELECT;
Em aplicativos que chamam a função;
Na definição de outra função definida pelo
usuário;Para parametrizar uma exibição ou aprimorar a
funcionalidade de uma exibição indexada;
Para definir uma coluna em uma tabela;
Para definir uma restrição CHECK em uma coluna;
Para substituir um procedimento armazenado.





Sintaxe



--Transact-SQL Scalar Function Syntax

CREATE FUNCTION nome_funcao

( [ {
@nome_parametro [ AS ][ type_schema_name. ]&nbsp;tipo_dado_parametro 

&nbsp;&nbsp;&nbsp;&nbsp;[ =&nbsp;default ] [ READONLY ] } 

&nbsp;&nbsp;&nbsp;&nbsp;[ ,...n ]

&nbsp;&nbsp;]

)

RETURNS tipo_dado_retorno

&nbsp;&nbsp;&nbsp;&nbsp;[ WITH
 [ ,...n ] ]

&nbsp;&nbsp;&nbsp;&nbsp;[ AS ]

&nbsp;&nbsp;&nbsp;&nbsp;BEGIN 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function_body


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RETURN
scalar_expression

&nbsp;&nbsp;&nbsp;&nbsp;END

[ ; ]

--Transact-SQL Inline Table-Valued Function
Syntax 

CREATE FUNCTION [ schema_name. ] nome_funcao

( [ {
@nome_parametro [ AS ] [ type_schema_name. ]&nbsp;tipo_dado_parametro

&nbsp;&nbsp;&nbsp;&nbsp;[ = default ] [ READONLY ] } 

&nbsp;&nbsp;&nbsp;&nbsp;[ ,...n ]

&nbsp;&nbsp;]

)

RETURNS TABLE

&nbsp;&nbsp;&nbsp;&nbsp;[ WITH
 [ ,...n ] ]

&nbsp;&nbsp;&nbsp;&nbsp;[ AS ]

&nbsp;&nbsp;&nbsp;&nbsp;RETURN [ ( ]
select_stmt [ ) ]

[ ; ]



Instruções válidas





Todas as instruções a seguir são
válidas em uma função, ou seja, podemos utilizar no interior de uma função:



Instruções de atribuição.
Instruções de controle de fluxo
     com exceção das instruções TRY...CATCH.
Instruções DECLARE que definem
     variáveis de dados locais e cursores locais.
Instruções SELECT que contêm
     listas de seleção com expressões que atribuem valores a variáveis locais.
Operações de cursor que fazem
     referência a cursores locais que são declaradas, abertas, fechadas e desalocadas
     na função.&nbsp;Apenas instruções FETCH que atribuem valores a variáveis
     locais usando a cláusula INTO são permitidas. Instruções FETCH que
     retornam dados ao cliente não são permitidas.
Instruções INSERT, UPDATE e DELETE
     que modificam variáveis de tabela locais.
Instruções EXECUTE que chamam
     procedimentos armazenados estendidos.




Limitações e restrições



Quando criamos funções
não podemos utilizá-las para modificar o estado do banco, também não podemos usar
OUTPUT INTO para retornar para uma tabela.



Aninhamento



As funções criadas podem ser
aninhadas, ou seja, utilizar uma dentro de outra, até o 32º nível. Caso seja
excedido esse número haverá uma falha na cadeia inteira de funções.



Exemplos



Comecemos a mostrar alguns
exemplos de funções, vamos iniciar mostrando uma função que faz uma coisa
simples, uma função que mostra o número da semana, tendo como parâmetro de
entrada uma data especifica;



IF OBJECT_ID (N'dbo.NmSemana', N'FN') IS NOT NULL

&nbsp;&nbsp;&nbsp;
DROP FUNCTION
dbo.NmSemana;

GO

CREATE FUNCTION
dbo.NmSemana (@DATE datetime)

RETURNS int

WITH EXECUTE
AS CALLER

AS

BEGIN

&nbsp;&nbsp;&nbsp;&nbsp; DECLARE
@NmSemana int;

&nbsp;&nbsp;&nbsp;&nbsp; SET
@NmSemana= DATEPART(wk,@DATE)+1

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -DATEPART(wk,CAST(DATEPART(yy,@DATE) as CHAR(4))+'0104');

--Special cases: Jan 1-3 may
belong to the previous year

&nbsp;&nbsp;&nbsp;&nbsp; IF (@NmSemana=0) 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET
@NmSemana=dbo.NmSemana(CAST(DATEPART(yy,@DATE)-1 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AS CHAR(4))+'12'+ CAST(24+DATEPART(DAY,@DATE) AS CHAR(2)))+1;

--Special case: Dec 29-31
may belong to the next year

&nbsp;&nbsp;&nbsp;&nbsp; IF ((DATEPART(mm,@DATE)=12) AND 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((DATEPART(dd,@DATE)-DATEPART(dw,@DATE))&gt;= 28))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET
@NmSemana=1;

&nbsp;&nbsp;&nbsp;&nbsp; RETURN(@NmSemana);

END;

GO

SET DATEFIRST
1;

SELECT
dbo.NmSemana(CONVERT(DATETIME,'08/14/2013',101)) AS 'Número da Semana';



Agora vamos criar uma função para
retornar uma tabela especifica de acordo um o código do produto passado.






IF OBJECT_ID (N'FNMovimProdutos', N'IF') IS NOT NULL

&nbsp;&nbsp;&nbsp;
DROP FUNCTION
FNMovimProdutos;

GO

CREATE FUNCTION
FNMovimProdutos (@codigo
int)

RETURNS TABLE

AS

RETURN 

(

&nbsp;&nbsp;&nbsp; SELECT
DESC_PRODUTO, QTD_PRODUTO, TP_MOVIMENTO,
DTH_MOVIMENTO, SUM(VR_MOVIMENTO)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TBPRODUTO
P INNER JOIN 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TBMOVIMENTOPRODUTO
M ON M.CD_PRODUTO
= P.CD_PRODUTO INNER JOIN

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TBMOVIMENTODIARIO D ON D.CD_MOVIMENTO = M.CD_MOVIMENTO

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE
CD_PRODUTO = @CODIGO

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GROUP BY CD_PRODUTO,
DESC_PRODUTO, QTD_PRODUTO, TP_MOVIMENTO,
DTH_MOVIMENTO

);

GO





Para invocar a função,
execute esta consulta.





SELECT *
FROM FNMovimProdutos (6);




Aqui encerramos mais esse arquivo sobre a linguagem SQL onde mostramos um pouco da utilização de FUNÇÕES, caso tenha dúvidas ou sugestões, não se esqueça de comentar. No próximo artigo vamos falar um pouco sobre as TRIGGERS ou GATILHOS que podemos colocar nas tabelas.






Grande abraço e até lá.



Artigos anteriores:

Desvendando o SQL - Parte I - Introdução
Desvendando o SQL - Parte II - Criando um Banco de Dados e Tabelas

Desvendando o SQL - Parte III - Alterando Registros


Desvendando o SQL - Parte IV - Consultas


Desvendando o SQL - Parte V - Visões

Desvendando o SQL - Parte VI - Estruturas Condicionais e de Repetição
Desvendando o SQL - Parte VII - Cursores
Desvendando o SQL - Parte VIII - Conversão de Valores
Desvendando o SQL - Parte IX - Procedimentos Armazenados