Vous êtes sur la page 1sur 15

FUNCOES SQL

Funes de agrupamento:
AVG() = Retorna o valor mdio de uma coluna especfica
BINARY_CHECKSUM() = O valor do BINARY_CHECKSUM computado sobre uma linha ou uma tabela
ou sobre uma lista de expresses. BINARY CHECKSUM usada para detectar alteraes em uma linha ou
uma tabela.
CHECKSUM() = O valor de CHECKSUM computado sobre uma linha ou uma tabela, ou sobre uma lista
de expresses. CHECKSUM usada para construir ndices de hash.
CHECKSUM_AGG() = O valor de CHECKSUM de um grupo. Valores nulos so ignorados.
COUNT() = Retorna o nmero de linhas
COUNT_BIG() = igual ao COUNT mas o COUNT_BIG sempre retorna um tipo de dados bigint.
MAX() = Retorna o valor mximo de uma coluna especfica
MIN() = Retorna o valor mnimo de uma coluna especfica
SUM() = Retorna a soma de uma coluna especfica
STDEV() = Desvio padro de todos os valores
STDEVP() = Desvio padro da populao
VAR() = Varincia estatistica de todos os valores
VARP() = Varincia estatstica de todos os valores da populao
Funes de manipulao de strings:
ASCII(string) = pega o valor em ASCII da string
CHAR(integer) = troca inteiro do ASCII em um caracter
LEN(string) = Identifica o comprimento de uma expresso em caracteres
LOWER(string) = converte uma string uppercase para lowercase.
LTRIM(string) = remove os espaos em branco
PATINDEX(posicao, expressao) = devolve a posico de uma string dentro de um texto. Se no encontrar,
retorna zero.
REPLICATE(string, integer) = Repete N vezes um caractere especificado
REVERSE(string) = retorna o inverso de uma expressao
RTRIM (string) = remove os espaos em branco direita de uma string
SPACE(integer) = que retorna o nmero de espaos em branco informados no parmetro
STUFF(string texto, X, Y, string texto_a_inserir) = apaga da string "texto" os y caracteres a partir da
posio x e os substitui por "texto_a_inserir"
SUBSTRING(string texto, posicao_inicial, tamanho) = retorna uma string com o comprimento definido
em "tamanho" extraida da string "texto", a partir da "posicao_inicial"
UPPER(string) = retorna string em maiusculas
Funes de manipulao de data/hora:
nomes das partes de data:
Year = yy, yyyy
Quarter = qualquer, que
Month = mm, m
Dayofyear = dy, y
Day = dd, d
Week = wk, ww
Hour = hh
Minute = mi, n
Second = ss, s
Millisecond = ms
DATEADD (parte, numero, data) = adiciona um valor a parte de uma data

DATEDIFF (parte, data inicial, data final) = subtrai a data inicial da data final, indicando o resultado na
unidade definida em "parte"
GETDATE() = retorna a data atual do sistema
DATENAME (parte, data) = retorna o nome da parte de uma data
DATEPART(parte, data) = retorna a parte de uma data
Funes de Sistema:
CAST(expressao as datatype) = converte uma expressao no datatype informado
COL_LENGTH(nome_da_tabela, nome_da_coluna) = retorna o tamanho da coluna
COL_NAME(id_da_tabela, id_da_coluna) = retorna o nome da coluna
DATALENGTH(expressao) = retorna o numero de bytes usados para armazenar a expressao
DB_ID(nome_do_banco) = retorna o ID do banco informado
DB_NAME(id_do_banco) = retorna o nome do banco
HOST_ID() = retorna a ID da estao que est acessando o SQL Server
HOST_NAME() = retorna o nome da estao que est acessando o SQL Server
IDENT_INCR(nome_da_tabela_ou_view) = retorna o valor incrementado
IDENT_SEED(tabela_ou_view) = retorna o valor inicial da coluna
INDEX_COL(nome_da_tabela, indice_id, chave_id) = retorna o nome da coluna que participa do ndice
ISNULL(expressao, valor) = se a expressao for null, troca pelo valor especificado
ISNUMERIC(expressao) = retorna 1 se a expressao for numerica e 0 se no for
NEWID() = retorna um novo valor do tipo uniqueidentifier
NULLIF(expressao_1, expressao_2) = retorna nulo se as duas expressoes forem equivalentes. Se no
forem, retorna a primeira expressao.
OBJECT_ID(nome_do_objeto) = retorna o ID de um objeto, a partir do nome fornecido
OBJECT_NAME(ID_do_objeto) = retorna o nome do objeto, a partir do ID fornecido
PARSENAME(objeto, parte) = retorna a parte do nome de um objeto, desde que tenha sido qualificado
STATS_DATE(tabela_id, indice_id) = retorna a data em que as estatsticas do ndice foram atualizadas
SUSER_SID(nome_do_usuario) = retorna o ID do usuario informado
SUSER_NAME(usuario_id) = retorna o id do usurio no servidor. O argumento opcional.
SUSER_SNAME(id_do_usuario) = retorna o nome do usuario informado. Se nenhum ID de usuario for
passado para a funo, retorna o nome do usuario logado
USER_ID(nome_do_usuario) = retorna o ID do usuario informado para o BD em uso
USER_NAME(id_do_usuario) = retorna o usuario conectado ao BD
Funes Matematicas:
ABS(numero) = retorna o valor absoluto do numero
ACOS(float) = retorna o arco-coseno do numero informado
ASIN(float) = retorna o arco-seno do numero informado
ATAN(float) = retorna o arco-tangente do numero informado
ATN2(Float expressao_1, float expressao_2) = Arco-tangente do valor definido pela diviso da primeira
expresso pela segunda
CEILING(numero) = retorna o menor inteiro que seja maior ou igual ao numero informado
COS(float) = retorna o coseno do numero informado
COT(float) = retorna o cotangente do numero informado
DEGREES(numero) = converte radianos para graus
EXP(float) = retorna o exponencial de um numero especificado
FLOOR(numero) = retorna o maior inteiro que seja menor ou igual ao numero informado
LOG(float) = retorna o logaritmo natural do numero informado
LOG10(float) = retorna o logaritmo base 10 do numero informado
PI() = retorna o valor de PI 3.1415926535897931.
POWER(numero, potencia) = retorna o valor elevado potencia informada
RADIANS(numero) = converte graus para radianos
RAND(expressao) = um nmero aleatrio entre 0 e 1. Expresso opcional e ser usada como semente da

cadeia pseudo-aleatria
ROUND(numero, precisao, arredonda_ou_trancar) = arredonda ou tranca o numero fornecido de acordo
com a precisao informada. Se o terceiro parametro no for passado para a funao, o numero arredondado.
Se quiser que o numero seja truncado, deve-se fornecer o valor 1
SIGN(numero) = retorna sinal positivo, negativo ou zero do numero
SIN(float) = retorna o seno do angulo especificado
SQRT(float) = retorna a raiz quadrada de um numero
TAN(float) = retorna a tangente de um numero informado
SQUARE(float) = retorna o quadrado de um numero
Funo de converso:
CONVERT(tipo(tamanho), expresso, estilo) = converte a expresso para o tipo de dado. O tamanho e o
estilo so opcionais
No atual post prentende-se discutir/exemplificar alguns pontos que podero serem teis tanto no
entendimento/clareza quanto na performance das queries e stored procedure.
No so regras, so apenas "dicas" cada caso um caso. Utilize-as sempre que possvel, lembrando que
alguns casos poderemos perder em performance para atender determinadas situaes.
Esta dicas podem ser aplicadas em quase todos os bancos de dados que utilizem padro ANSI.
1. Uso do Select *
Sempre que possvel evitar o uso de select * mesmo que a Stored Procedure retorne todos as
colunas de uma tabela. Com isso, garante-se a segurana e manutenabilidade da SP, pois sabe-se
exatamente quais parmetros ela retorna assim que se visualiza o seu cdigo.
2. Uso de > ou >=
Situao: A query :
CODE
select c1,c2 from t where a > 3
e a tabela possui ndice em a..
Se houver muitas linhas com a = 3, o engine do banco de dados far scan de muitas pginas at
encontrar a > 3.
mais eficiente se escrita da forma:
CODE
select c1,c2 from t where a >= 4

3. Exists ou Not Exists


De maneira geral o uso de EXISTS e IN mais eficiente que NOT EXISTS e NOT IN.
Situao:
CODE

if not exists ( select a from t where a = 3 )


begin .....grupo 1
end
else
begin .....grupo 2
end
mais eficiente se escrita da forma
CODE
if exists ( select a from t where a =3 )
begin ... grupo 2
end
else
begin ... grupo 1
end

No SELECT de um EXISTS tomar cuidado para no colocar * ou colunas que no sejam ndice
cluster, pois o EXISTS
no necessita retornar colunas somente verificar se a linha existe ou no. Assim, utilizar if exists:
CODE
select 1 from t where a > 3
ao invs de if exists:
CODE
( select * from t where a > 3)

4. Subqueries com clusula de outer-join restritiva


CODE
select w from outer where y = 1 and x = (select sum(a) from inner where inner.b = outer.z )

Ser quebrada pelo bancod e dados nos seguintes passos


CODE
select outer.z, summ = sum(inner.a)
into #work from outer, inner
where inner.b = outer.z and outer.y = 1
group by outer.z

select outer.w
from outer, #work
where outer.z = #work.z and outer.y = 1 and outer.x = #work.summ

O bancod de dados copia a clusula search ( y = 1 ) para a subquery, mas no copia clusula join.
Isto porque copiando a clusula search, sempre tornar a query mais eficiente, mas copiando a
clusula join pode em muitos casos tornar a query mais lenta. A cpia da clusula join s eficiente
quando ela extremamente restritiva, mas o banco de dados faz a quebra antes do otimizador atuar.
Ento, para tornar a query mais eficiente, conhecendo previamente a alta restritividade da clusula
join, pode-se copiar a clusula join para a subquery como no exemplo abaixo :
tab_x -> tabela grande
tab_y -> tabela pequena
CODE
select a from tab_x, tab_y
where tab_x.coluna_valor_unico = tab_y.a and tab_x.b = ( select sum from tabela_interna where
tab_x.d = tabela_interna.e and tab_x.coluna_valor_unico = tab_y.a)

5. Criao de tabelas dentro de stored procedures


Quando uma tabela criada e utilizada dentro de uma mesma stored procedure, o otimizador no tem
conhecimento das suas estatsticas, e assume que esta tabela tem 100 linhas e 10 pginas. Se a tabela
criada muito grande, esta suposio pode levar o otimizador a calcular um plano de acesso no
otimizado. Para evitar este problema, crie a tabela em uma procedure e utilize-a em outra. Isto ser
objeto de especificao durante o Diagrama de Cenrios.
6. Variveis ou parmetros na clusula where
O otimizador no tem informaes sobre o valor de uma varivel, mas, em tempo de compilao,
sabe o valor de um parmetro. Isso posto, a utilizao de parmetros em clusula where, leva o
otimizador a produzir um plano de acesso mais eficiente.
Por exemplo, a procedure
CODE
create procedure s_p1 as declare @x int
select @x = b1 from t where a1 = 3
select a from t2 where b1 = @x
pode ser reescrita como :
create procedure s_p1 as declare @x int
select @x = b1 from t where a1 = 3
exec s_p2 @x
create s_p2 @x int as select a from t2 where b1 = @x

7. COUNT x EXISTS
Para testes de existncia sempre mais eficiente utilizar EXISTS do que COUNT. Quando se utiliza
o COUNT o banco de dados no sabe que se est fazendo um teste de existncia e continua
pesquisando todas as linhas qualificadas. J utilizando EXISTS, o banco de dados sabe que um
teste de existncia e interrompe a pesquisa quando encontra a primeira linha qualificada.
Este mesmo raciocnio vlido quando se utiliza COUNT no lugar de IN ou ANY.
8. OR x UNION
O banco de dados no consegue otimizar clusulas de join ligadas por OR. Neste caso mais
eficiente ligar os conjuntos de resultados por UNION.
Por exemplo :
CODE
select a from tab1,tab2 where tab1.a = tab2.a OR tab1.x = tab2.x

pode ser reescrito como :


CODE
select a from tab1, tab2
where tab1.a = tab2.a
UNION
select a from tab1, tab2
where tab1.x = tab2.x

A diferena que na segunda forma, so eliminadas as linhas duplicadas, o que pode ser contornado
com UNION ALL.
9. MAX e MIN Agregados
O banco de dados utiliza uma otimizao especial para MAX e MIN quando h um ndice na coluna
agregada. Para o MIN a pesquisa interrompida quando encontra a primeira linha qualificada.
Para o MAX, o banco de dados vai diretamente para o final do ndice e pega a ltima linha.
Os casos onde estas otimizaes especiais no so utilizadas:
- a expresso do MAX ou MIN no uma coluna.
- a coluna do MAX ou MIN no a primeira do ndice
- existe outro comando agregado na query.
- existe uma clusula de GROUP BY.
- se existe clusula WHERE, a otimizao especial de MAX no utilizada.
Se houver possibilidade de se conseguir otimizao especial, vale a pena separar em vrias queries.
mais eficiente utilizar o ndice vrias vzes, do que fazer scan table uma nica vez.
Em alguns casos, pode ser mais eficiente no utilizar a otimizao especial do MIN. Por exemplo, se
h uma clusula where em outro ndice, quanto mais restritivo for o WHERE, menos eficiente fica a
otimizao especial do MIN. A soluo convencer o otimizador a no utilizar a otimizao especial

do MIN, colocando, por exemplo, duas agregaes na query.


Por exemplo :
CODE
select MIN(coluna1)
from tab where coluna2 =

O banco de dados utilizar aqui a otimizao especial do MIN, e far um scan em quase todo o
ndice, pois a qualificao na clusula WHERE fora esta situao. Se colocarmos mais um
aggregate, convenceremos o otimizador a utilizar o processo normal, criando um plano de acesso
pelo ndice da coluna2, neste caso, mais eficiente que a otimizao especial do MIN.
CODE
select MIN(coluna1), MAX[coluna2)
from tab where coluna2 =

10. Joins e Datatypes


Se a clusula join utiliza datatypes diferentes, um deles ser convertido para o outro. O datatype
convertido o hierarquicamente inferior. O otimizador no consegue escolher um ndice na coluna
que convertida.
O ideal evitar este tipo de join, mas se no for possvel, pode-se explicitamente converter o lado do
join que tem o menor custo de no utilizao do ndice.
Por exemplo :
CODE
select c1,c2 from tab1, tab2
where tab1.col_char_75 = convert ( char(75), tab2.col_varchar_75 )

11. Parmetros e Datatypes


O otimizador pode utilizar o valor de um parmetro para calcular o custo de um plano. Mas o banco
de dados no poder utilizar valores de parmetros convertidos. O ideal ento garantir que o
parmetro tem o mesmo datatype da coluna com a qual ele ser comparado.
Por exemplo :
CODE
create procedure s_p @x varchar(30) as select c1,c2 from tab where coluna_char_30 = @x
pode ser reescrito como:

CODE
create procedure s_p @x char(30) as select c1,c2 from tab where coluna_char_30 = @x

12. Testar retorno de comando SQL


Aps um comando SQL (select, insert, update, delete) sempre necessrio testar duas variveis para
um correto processamento da Stored Procedure: @@error (cdigo de retorno do banco de dados ) e
@@rowcount (quantidade de linhas retornadas pelo comando). Estas variveis devem ser testadas
para que a SP possa dar como retorno os cdigos de erro -1001 (erro banco de dados ) e -1002 (no
encontrou registro). No caso do raiserror, retornar 40001 e 40002 respectivamente.
Para testar siga o exemplo:
CODE
declare @erro smallint,
@numlin smallint
select a from t where a > 3
/* sempre salvar o valor de @@error em uma varivel pois para cada
comando SQL o banco de dados gera um @@error. */
select @erro = @@error
@numlin = @@rowcount
if @erro != 0
return -1001 /* erro banco de dados */
if @numlin = 0
return -1002 /* no encontrou registro */

13. Stored Procedure chamadora


Para as SPs consideradas chamadoras, ou seja, aquelas que chamam outras SPs
deve-se tomar um cuidado especial com os cdigos de retorno (vide quadro de cdigos). Alm dos
cdigos padronizados (0, -1001, -1002, ...) a SP ainda pode retornar cdigos prprios dela durante a
execuo (cdigos -1 a -14). Estes cdigos sinalizam que houve algum tipo de problema para a
execuo da SP: no achou a SP, no existe permisso para execut-la, entre outras. Testar na SP
chamadora estes cdigos de retorno tambm.
Exemplo:
CODE
create procedure s_teste
as declare @return int /* p/ cdigo de retorno */
/* executa s_teste2 buscando seu cdigo de retorno */
execute @return = s_teste2

/* testa retorno de s_teste2 */


if @return != 0
begin raiserror 40001
return -1001 /* erro banco de dados */
end
else
begin raiserror 40000
return 0 /* OK */
end

14. Utilizao do comando RAISERROR


O uso do RAISERROR no cdigo obrigatrio para as SPs chamadoras ou que retornem mltiplas
todoss da mesma tabela ou de tabelas diferentes. Isto faz-se necessrio para facilitar e viabilizar o
controle de erros nas aplicaes PowerBuilder. O RAISERROR deve ser colocado antes de todos os
returns do cdigo da SP. Ver padronizao dos cdigos no quadro CDIGOS DE RETORNO. Nas
demais SPs fica a critrio do coordenador de cada equipe de desenvolvimento, a deciso pela
obrigatoriedade da utilizao do RAISERROR.
Exemplo: vide cdigo SP do item acima.
15. Uso de campos formato DATA (smalldatetime e datetime)
Tomar bastante cuidado com a utilizao de campos no formato DATA, principalmente para
utilizao de datas zeradas e datas com 99999999. No banco de dados este conceito perdeu o sentido
pois s so aceitas datas vlidas para um campo formato DATA.
Assim, utilizar
1900/01/01 para representar DATA = 0
e
2070/12/31 para representar DATA = 99999999.
Estas datas so os limites abaixo e acima para os campos smalldatetime. Para casos aonde este range
no seja suficiente, buscar orientao com o Suporte/Adm. de Dados.

Neste tpico vamos aprender como manipular Data (DATETIME ou SMALLDATETIME) no SQL
Server.
No um texto dogmtico nem com pretenso de esgotar o assunto. As dicas e exemplos postados aqui
representam o meu aprendizado dirio. Funcionam! Porm no so verdades absolutas.
1. Sempre criar campos data com o formato DATETIME ou SMALLDATETIME. A diferena entre
os dois tipos podem ser detalhadas nos Books Online. O exemplo a seguir mostra de forma
simplificada como cada tipo atua:
CODE
---Retorna Data do sistema completa: AAAA-MM-DD 00:00:00.000

SELECT CAST(GETDATE() AS DATETIME)


---Retorna Data do sistema completa (com arredondamento): AAAA-MM-DD 00:00:00
SELECT CAST(GETDATE() AS SMALLDATETIME)
--- Exemplos do Books Online
---Retorna: 2000-05-08 12:35
SELECT CAST('2000-05-08 12:35:29.998' AS SMALLDATETIME)
SELECT CONVERT(SMALLDATETIME,'2000-05-08 12:35:29.998')
---Retorna: 2000-05-08 12:36
SELECT CAST('2000-05-08 12:35:29.999' AS SMALLDATETIME)
SELECT CONVERT(SMALLDATETIME,'2000-05-08 12:35:29.999')
-OBS: Notem que tanto a funo CAST como CONVERT retorna o mesmo resultado.
No existem impedimentos para se gravar uma data em um campo VARCHAR e depois utilizar
CAST ou CONVERT para manipul-lo. Porm como o tipo VARCHAR no impe CONTRAINT
para validar uma data, facilidade nativa dos tipos DATETIME/SMALLDATETIME, pode permitir
a entrada de uma data invlida. Assim sendo se a aplicao por algum problema passar uma data
invalida o banco de dados gravar a data invlida sem retornar erro algum. claro que a aplicao
realmente dever consistir e formatar a data a ser envia para o banco. Porm definindo a data no
formato correto esta consistncia ser garantida a nvel de banco de dados, alm da aplicao.
No post: http://forum.imasters.com.br/index.php?showtopic=223962 este assunto tratado com
um exemplo real.
2. Criando campos e variveis do tipo data:
CODE
--Criando variveis locais do tipo data
DECLARE @DT_INICIO DATETIME
DECLARE @DT_INICIO SMALLDATETIME
--Criando campos tipo data em tabela
CREATE TABLE #TMP (NU_COD INT, DT_INICIO DATETIME)
CREATE TABLE #TMP (NU_COD INT, DT_INICIO SMALLDATETIME)
3. A forma como o banco de dados tratar/gravar/exibr o campo data:
CODE
--- Exemplos do Books Online
SET DATEFORMAT mdy
DECLARE @datevar datetime
SET @datevar = '12/31/98'
SELECT @datevar
SET DATEFORMAT ydm
SET @datevar = '98/31/12'
SELECT @datevar
SET DATEFORMAT ymd

SET @datevar = '98/12/31'


SELECT @datevar
No post: http://forum.imasters.com.br/index.php?showtopic=223962 nosso companheiro
eriva_br d uma aula sobre o assunto. Vale uma conferida!
4. Inserindo registros em campos datas
CODE
CREATE TABLE #ATIVIDADES (DESCRICAO_ATIVIDADE VARCHAR(30),DT_INI
DATETIME, DT_FIM DATETIME)
--Inserindo DT_INI no formato DD/MM/AAAA com a hora
--e DT_FIM no formato DD/MM/AAAA sem a hora
INSERT INTO #ATIVIDADES (DESCRICAO_ATIVIDADE,DT_INI,DT_FIM)
VALUES ('Requisitos','01/01/2005 00:00:00','01/01/2006')
--Inserindo DT_INI no formato AAAA/MM/DD sem a hora
--e DT_FIM no formato DD/MM/AAAA sem a hora
INSERT INTO #ATIVIDADES (DESCRICAO_ATIVIDADE,DT_INI,DT_FIM)
VALUES ('Modelagem','2006/01/02 ','05/07/2006')
--Inserindo DT_INI no formato AAAA/DD/MM com a hora
--e DT_FIM no formato AAAA/DD/MM com a hora
INSERT INTO #ATIVIDADES (DESCRICAO_ATIVIDADE,DT_INI,DT_FIM)
VALUES ('Implementao','2006/07/06 00:00:00','2007/04/25 00:00:00')
Como pode ser visto as datas podem ser inseridas de vrias formas com hora ou no. Caso a hora no
seja informada ser usada 00:00:00 como padro. Aqui onde trabalhamos normalmente enviamos a
data para o SQL no formato AAAA/MM/DD pois neste formato grava-se a data em qualquer banco
de dados ANSI.
5. Converter, mascarar, recuperar informaes campos data:
Utilizando a funo CONVERT pode-se retornar o contedo do campo data das seguintes formas:
CODE
SELECT CONVERT(VARCHAR(12),GETDATE(),101) AS '101',
CONVERT(VARCHAR(12),GETDATE(),102) AS '102',
CONVERT(VARCHAR(12),GETDATE(),103) AS '103',
CONVERT(VARCHAR(12),GETDATE(),104) AS '104',
CONVERT(VARCHAR(12),GETDATE(),105) AS '105',
CONVERT(VARCHAR(12),GETDATE(),106) AS '106',
CONVERT(VARCHAR(12),GETDATE(),107) AS '107',
CONVERT(VARCHAR(12),GETDATE(),108) AS '108',
CONVERT(VARCHAR(12),GETDATE(),109) AS '109',
CONVERT(VARCHAR(12),GETDATE(),110) AS '110',
CONVERT(VARCHAR(12),GETDATE(),111) AS '111',
CONVERT(VARCHAR(12),GETDATE(),112) AS '112',
CONVERT(VARCHAR(12),GETDATE(),113) AS '113',
CONVERT(VARCHAR(12),GETDATE(),114) AS '114',
CONVERT(VARCHAR(12),GETDATE(),120) AS '120',
CONVERT(VARCHAR(12),GETDATE(),121) AS '121'

A funo CONVERT alm de devolver a data formatada, ou parte da mesma, permite efetuar a
converso do campo data para outros formatos. Nesta caso pode-se utilizar a funao CAST para
obter-se o mesmo resultado. Para concatenar um texto com uma data veja os exemplos:
CODE
SELECT CONVERT(VARCHAR(10),GETDATE(),103) + ' a data de hoje'
SELECT CAST(GETDATE() AS VARCHAR(10)) + ' a data de hoje'
Normalmente utilizo o CONVERT e no o CAST, mas cada caso um caso.
Obs: Muita ateno no resultado da converso de datas para outros formatos. As vezes no ocorre a
concatenao e sim uma soma, principalmente na converses para formato numrico.
6. Manipulando partes de data:
CODE
SELECT YEAR(GETDATE()) AS ANO,
MONTH(GETDATE()) AS MES,
DAY(GETDATE()) AS DIA
---Utlizando DATEPART que retorna um INTEIRO contendo informaes
--sobre o campo data
SELECT DATEPART(YEAR, GETDATE()) AS ANO,
DATEPART(MONTH, GETDATE()) AS MES,
DATEPART(DAY, GETDATE()) AS DIA,
DATEPART(DAYOFYEAR, GETDATE()) AS DIA_ANO,
DATEPART(WEEK, GETDATE()) AS SEMANA,
DATEPART(HOUR, GETDATE()) AS HORA,
DATEPART(MINUTE, GETDATE()) AS MINUTO
---Utlizando DATENAME que retorna uma STRING(caracter) contendo informaes
--sobre o campo data
SELECT DATENAME (YEAR, GETDATE()) AS ANO,
DATENAME (MONTH, GETDATE()) AS MES,
DATENAME (DAY, GETDATE()) AS DIA,
DATENAME (DAYOFYEAR, GETDATE()) AS DIA_ANO,
DATENAME (WEEK, GETDATE()) AS SEMANA,
DATENAME (HOUR, GETDATE()) AS HORA,
DATENAME (MINUTE, GETDATE()) AS MINUTO
Mais exemplos e particularidades de cada funo pr-atividade e Books Online(procure por Date
and Time Functions). :assobiando:
7. Datas e matemtica. possvel? :devil:
CODE
---DATEDIFF retorna um INTEITO como resultado de operaes
--entre dua datas
DECLARE @DT_EXEMPLO DATETIME
SET @DT_EXEMPLO = '1966/01/01'

SELECT DATEDIFF(YEAR, @DT_EXEMPLO , GETDATE()) AS ANO,


DATEDIFF(MONTH, @DT_EXEMPLO , GETDATE()) AS MES,
DATEDIFF(DAY, @DT_EXEMPLO , GETDATE()) AS DIAS
---DATEADD retorna um DATETIME como resultado de adio entre datas
-SELECT DATEADD(DAY, -10 , GETDATE()) AS DATA_ATUAL_MENOS_10_DIAS,
DATEADD(DAY, 10 , GETDATE()) AS DATA_ATUAL_MAIS_10_DIAS,
DATEADD(YEAR, -10 , GETDATE()) AS DATA_ATUAL_MENOS_10_ANOS,
DATEADD(YEAR, 10 , GETDATE()) AS DATA_ATUAL_MAIS_10_ANOS
De novo, novamente! Mais exemplos e particularidades de cada funo pr-atividade e Books
Online(procure por Date and Time Functions). :assobiando:
8. O exemplo a seguir cria uma tabela temporria e executa vrios selects utilizando campos tipo data:
CODE
CREATE TABLE #ATIVIDADES (DESCRICAO_ATIVIDADE VARCHAR(30),DT_INI
DATETIME, DT_FIM DATETIME)
INSERT INTO #ATIVIDADES (DESCRICAO_ATIVIDADE,DT_INI,DT_FIM) VALUES
('Requisitos','2005/01/01 00:00:00','2006/01/01 00:00:00')
INSERT INTO #ATIVIDADES (DESCRICAO_ATIVIDADE,DT_INI,DT_FIM) VALUES
('Modelagem','2006/01/02 00:00:00','2006/07/05 00:00:00')
INSERT INTO #ATIVIDADES (DESCRICAO_ATIVIDADE,DT_INI,DT_FIM) VALUES
('Implementao','2006/07/06 00:00:00','2007/04/25 00:00:00')
INSERT INTO #ATIVIDADES (DESCRICAO_ATIVIDADE,DT_INI,DT_FIM) VALUES
('Testes','2007/04/26 00:00:00','2007/06/20 00:00:00')
INSERT INTO #ATIVIDADES (DESCRICAO_ATIVIDADE,DT_INI,DT_FIM) VALUES
('Homoogao','2007/06/21 00:00:00','2007/07/28 00:00:00')
INSERT INTO #ATIVIDADES (DESCRICAO_ATIVIDADE,DT_INI,DT_FIM) VALUES
('Implantao','2007/07/28 00:00:00','2007/11/25 00:00:00')
--- Calculando a diferena entre a DT_INI e DT_FIM utilizando funo DATADIFF
-PRINT 'DT_FIM - DT_INI:'
SELECT CONVERT(VARCHAR(10),DT_INI,103) AS DT_INI,
CONVERT(VARCHAR(10),DT_FIM,103) AS DT_FIM,
DATEDIFF(MONTH,DT_INI,DT_FIM) AS DIF_MES,
DATEDIFF(DAY,DT_INI,DT_FIM) AS DIF_DIAS,
DATEDIFF(WEEK,DT_INI,DT_FIM) AS DIF_SEMANA,
DATEDIFF(HOUR,DT_INI,DT_FIM) AS DIF_HORA,
DATEDIFF(MINUTE,DT_INI,DT_FIM) AS DIF_MINUTOS
FROM #ATIVIDADES
--- Diminui 2 dias e soma 2 dias na DT_INI
-PRINT 'SUBTRAI/SOMA DIAS EM DATA'
SELECT CONVERT(VARCHAR(10),DT_INI,103) AS DT_INI,
CONVERT(VARCHAR(10),DT_FIM,103) AS DT_FIM,
CONVERT(VARCHAR(10),DATEADD(DAY,-2,DT_FIM),103) AS DOIS_DIAS_ANTES,
CONVERT(VARCHAR(10),DATEADD(DAY,2,DT_FIM),103) AS DOIS_DIAS_DEPOIS

FROM #ATIVIDADES
---USANDO CASE NAS EXPRESSES:
-PRINT 'Data Atual (GETDATE()) - DT_FIM: '
SELECT CONVERT(VARCHAR(10),DT_INI,103) AS DT_INI,
CONVERT(VARCHAR(10),DT_FIM,103) AS DT_FIM,
DATEDIFF(DAY,DT_INI,DT_FIM) AS 'DT_FIM-DT_INI',
DATEDIFF(DAY,DT_INI,GETDATE()) AS 'GETDATE()-DT_INI',
DATEDIFF(DAY,DT_FIM,GETDATE()) AS 'GETDATE()-DT_FIM',
CASE
WHEN GETDATE() BETWEEN DT_INI AND DT_FIM THEN 'Iniciado'
WHEN (DATEDIFF(DAY,DT_FIM,GETDATE())) < 1 THEN 'A iniciar'
ELSE 'Finalizado'
END AS DE_SITUACAO,
CASE
WHEN (DATEDIFF(DAY,DT_FIM,GETDATE())) > 0 THEN '100 %'
ELSE
CASE
WHEN CONVERT(VARCHAR(15),100 - ((100 * (DATEDIFF(DAY,DT_FIM,GETDATE()) *
-1) ) /
DATEDIFF(DAY,DT_INI,DT_FIM))) < 0 THEN '0 %'
ELSE CONVERT(VARCHAR(15),100 - ((100 * (DATEDIFF(DAY,DT_FIM,GETDATE()) * -1) ) /
DATEDIFF(DAY,DT_INI,DT_FIM))) + '%'
END
END AS PERC_REAL
FROM #ATIVIDADES DROP TABLE #ATIVIDADES
Consideraes:

Exemplo de WHERE dinmico - sem utilizao de EXEC ou CASE


A stored procedure a seguir efetua uma consulta em uma tabela de CLIENTES utilizando como critrio os
campos: UF, CIDADE e BAIRRO.
A particularidade desta stored procedure que ele capaz efetuar a consulta de maneira dinmica.
Ou seja a stored procedure receber:

3 parmetros
EXEMPLO_WHERE_DINAMICO('UF','CIDADE','BAIRRO')

2 parmetros
EXEMPLO_WHERE_DINAMICO('UF','CIDADE')

1 parmetro
EXEMPLO_WHERE_DINAMICO('UF')

NENHUM parmetro
EXEMPLO_WHERE_DINAMICO()

E efetuar o filtro (WHERE) dinamicamente.


Segue cdigo da stored procedure: