Tem maiúscula? – SQL Server

Boa noite, caros leitores!

Venho-lhes escrever mais uma vez! Hoje um amigo do trabalho, Varley, teve uma necessidade interessante que nos fez pensar em uma função útil a ser feita no SQL Server.

A Necessidade: retornar todos os registros que contivessem alguma letra maiúscula.

Problema: o banco de dados utiliza o collation Latin1_General_CI_AI. Esse collation não faz diferenciação de maiúsculas e minúsculas. Para lembrar um pouco sobre collations leia: https://fredyesmeraldo.wordpress.com/2011/06/10/problemas-para-pesquisar-textos-que-possam-conter-acentos-errados-collations-do-sqlserver-resolverao-seu-problema/

Solução: para conseguir fazer a comparação se é maiúscula ou não, precisamos usar um artifício do SQL Server que converte um collation de uma string. Segue abaixo os códigos para retornar se existe maiúscula e outra função que retorna se existe minúscula. Daí para frente pode-se fazer diversas variações de funções (TodasMaiusculas, TodasMiusculas),

create function dbo.TemMinuscula(@texto varchar(max))
returns bit
as
begin
declare @letras as varchar(100)
declare @i as int
declare @j as int
declare @resultado as bit
declare @saiDoLoop as bit

select
@letras = ‘abcdefghijklmnopqrstuvwxzç’,
@resultado = 0,
@i = 1,
@j = 1,
@saiDoLoop = 0

while ( @i <= LEN(@texto) ) and (@saiDoLoop = 0)
begin
while ( @j <= LEN(@letras)) and (@saiDoLoop = 0)
begin
if SUBSTRING(@texto,@i,1) collate Latin1_General_CS_AI = SUBSTRING(@letras,@j,1) collate Latin1_General_CS_AI
begin
select
@resultado = 1,
@saiDoLoop = 1
end

select @j = @j + 1
end

select @i = @i + 1
select @j = 1
end

return @resultado
end

go

——————————————————–

create function dbo.TemMaiuscula(@texto varchar(max))
returns bit
as
begin
declare @letras as varchar(100)
declare @i as int
declare @j as int
declare @resultado as bit
declare @saiDoLoop as bit

select
@letras = ‘ABCDEFGHIJKLMNOPQRSTUVWXZÇ’,
@resultado = 0,
@i = 1,
@j = 1,
@saiDoLoop = 0

while ( @i <= LEN(@texto) ) and (@saiDoLoop = 0)
begin
while ( @j <= LEN(@letras)) and (@saiDoLoop = 0)
begin
if SUBSTRING(@texto,@i,1) collate Latin1_General_CS_AI = SUBSTRING(@letras,@j,1) collate Latin1_General_CS_AI
begin
select
@resultado = 1,
@saiDoLoop = 1
end

select @j = @j + 1
end

select @i = @i + 1
select @j = 1
end

return @resultado
end

Segue abaixo exemplo de utilização:

select dbo.TemMaiuscula(‘testE’)

Retorna 1
select dbo.TemMinuscula(‘TESTE’)

Retorna 0

 

Espero que possa ter sido útil a ideia e que vocês possam criar mais variações de funções a partir dessas!

Abraço! Boa noite!

Anúncios

Aprendendo a usar CURSOR – SQL Server

Boa noite!

Depois de um tempo se escrever é bom voltar a publicar algo um pouco mais substancial, hehehe…

Não gosto do consumo de processamento que eles geram, mas são muito úteis e bastante poderosos na manipulação de dados. Nesse primeiro momento não vou me aprofundar em CURSORES, mas apresentá-lo aqueles que estão iniciando no Microsoft SQL Server.

O que é CURSOR?

De maneira direta e simplista é uma espécie de ponteiro que nos ajuda a manipular e exibir dados consultados.

Como funciona?

Para entender é interessante um método de dividir como um cursor é declarado e o que ele faz. Segue abaixo:

1. Declara CURSOR (DECLARE)

2. Abre o CURSOR (OPEN)

3. Alimenta variáveis com os dados do CURSOR (FETCH)

4. Fecha e desaloca o CURSOR (CLOSE e DEALLOCATE)

<‘o’> Simples assim? Simples assim.

Vamos para um exemplo prático. Vou utilizar uma tabela cliente cujo o código de criação segue abaixo:

–Código de criação da tabela CLIENTE e alguns INSERTS só para exemplificar o CURSOR

create table CLIENTE
(
CodigoCliente int null,
NomeCliente varchar(50) null
)
go

insert into CLIENTE values (1,’Cliente 1′)
insert into CLIENTE values (2,’Cliente 2′)
insert into CLIENTE values (3,’Cliente 3′)
insert into CLIENTE values (4,’Cliente 4′)
insert into CLIENTE values (5,’Cliente 5′)

Agora vou utilizar o cursor fazer uma manipulação “inútil” para exibir os dados. É somente didática. Não serve de muita coisa, pois sem CURSOR seria imensamente fácil fazê-la. Vou utilizar nos comentários os passos que indiquei a vocês anteriormente para que fique mais fácil a compreensão:

–1. Declara CURSOR (DECLARE)
declare c_aprendendoCursor cursor for
select
CodigoCliente,
NomeCliente
from
CLIENTE

–2. Abre o CURSOR (OPEN)
open c_aprendendoCursor

–3. Alimenta variáveis com os dados do CURSOR (FETCH)
declare @cod int
declare @nome varchar(50)

fetch next from c_aprendendoCursor into @cod, @nome

print ‘Código do Cliente: ‘ + cast(@cod as varchar)
print ‘Nome do Cliente: ‘ + @nome
print ‘————————————————————————————‘

fetch next from c_aprendendoCursor into @cod, @nome

print ‘Código do Cliente: ‘ + cast(@cod as varchar)
print ‘Nome do Cliente: ‘ + @nome
print ‘————————————————————————————‘

fetch next from c_aprendendoCursor into @cod, @nome

print ‘Código do Cliente: ‘ + cast(@cod as varchar)
print ‘Nome do Cliente: ‘ + @nome
print ‘————————————————————————————‘

fetch next from c_aprendendoCursor into @cod, @nome

print ‘Código do Cliente: ‘ + cast(@cod as varchar)
print ‘Nome do Cliente: ‘ + @nome
print ‘————————————————————————————‘

–4. Fecha e desaloca o CURSOR (CLOSE e DEALLOCATE)
close c_aprendendoCursor
deallocate c_aprendendoCursor

Lembrando para quem já usa CURSOR que esse é um exemplo bem simplista! Por isso não vou me deter explicando maiores detalhes do CURSOR e nem sobre WHILE e @@FETCH_STATUS, etc, etc, etc…

Serão cenas do próximo capítulo! Rs

Espero que tenha sido útil. Até a próxima!

Resposta Desafio SQL Server – Cadê o meu join?

Boa noite!

Quanto tempo não escrevo? Rs… Vamos tentar manter regularidade, né?

Bom, antes de responder o Desafio, quero deixar todos os créditos para o incrível Fabrício Catae e seu blog http://blogs.msdn.com/b/fcatae/archive/2012/01/23/desafio-cad-234-meu-join.aspx

O desafio foi criado por ele e não tenho nenhum crédito sobre isso. Só achei interessante repassar, pois a resposta dele é um excelente exemplo do funcionamento do optimizer do SQL Server.

O Optimizer do SQL é inteligente para saber que RegiaoID não pode ser NULL, então quando é feita uma consulta que foge uma FK ou uma check constraint (no exemplo em questão: “WHERE regiaoId IS NULL”) o optimizer nem precisa acessar a tabela para ter certeza que não vai retornar nenhuma linha.

Até a próxima!

Desafio SQL Server – Cadê meu JOIN?!

Achei esse desafio em um site(no qual não vou dizer agora pros espertinhos não procurarem a resposta; porém, darei todo o crédito ao responsável pelo desafio depois, ok?!), e resolvi compartilhar com vocês.

O nome do desafio é Cadê o meu JOIN?

A resposta estarei postando em breve ou comentarei quando alguém acertar! Abraço a todos os amantes do SQL Server!

Uma pessoa me apresentou uma consulta SQL que relacionava os dados de cliente com os endereços.

SELECT c.* FROM Clientes c LEFT OUTER JOIN Regioes r
ON c.regiaoId = r.regiaoId AND
r.regiaoId IS NULL

O interessante é que o plano de execução gerada não possui JOIN entre tabelas. Surge a pergunta: CADÊ MEU JOIN???

image

O problema fica mais interessante quando substituimos o LEFT OUTER JOIN por um INNER JOIN, pois o plano de execução não apresenta a leitura em nenhuma tabela.

SELECT c.* FROM Clientes c INNER JOIN Regioes r
ON c.regiaoId = r.regiaoId AND
r.regiaoId IS NULL

image

A pergunta desse Desafio Ninja é:

O que aconteceu com o Join de tabela e com a operação de Table Scan?

Fico aguardando as respostas nos comentários!

Script usado:

CREATE TABLE Regioes
(regiaoId INT PRIMARY KEY,
   local VARCHAR(100) NOT NULL)

CREATE TABLE Clientes
  (id INT,
nome VARCHAR(50),
regiaoId INT FOREIGN KEY REFERENCES Regioes(regiaoId))

INSERT Regioes VALUES (1, ‘Norte’), (2, ‘Sul’)
INSERT Clientes VALUES (1, ‘Cliente1’, 1), (2, ‘Cliente2’, 1)
GO

SELECT c.* FROM Clientes c LEFT JOIN Regioes r
ON    c.regiaoId = r.regiaoId AND
r.regiaoId IS NULL

SELECT c.* FROM Clientes c INNER JOIN Regioes r
ON    c.regiaoId = r.regiaoId AND
r.regiaoId IS NULL

Microsoft apresenta tablet ‘Surface’ para concorrer com iPad

Washington, 18 jun (EFE).- A empresa americana Microsoft apresentou nesta segunda-feira seu tablet, o ‘Surface’, com o qual entrará no mercado para concorrer com o iPad da Apple. Segundo anúncio da companhia durante um evento em Los Angeles, o tablet irá operar com o sistema Windows 8, que ainda não foi lançado. O presidente-executivo da Microsoft, Steve Ballmer, apresentou o tablet, que tem uma tela de 10,6 polegadas e pesa 676 gramas. O ‘Surface’, com espessura de 9,3 milímetros, vem equipado com entrada USB 2.0, uma caixa de magnésio chamada ‘Vapor Mg’ e capacidade para 32 ou 64 GB. Além disso, haverá outro produto mais avançado, o Windows 8 Pro, com espessura de 13,5 milímetros e peso de 903 gramas, que incluirá microSDXC, USB 3.0 e capacidade para 64 ou 128 GB. Além disso, segundo o site da empresa, pode ser acrescentado no aparelho um teclado de material flexível, disponível em cinco cores brilhantes, para as pessoas que prefiram o teclado convencional em vez de escrever digitalmente na tela. A companhia não especificou a autonomia da bateria, nem falou sobre os preços dos tablets quando forem lançados, no último trimestre deste ano, por enquanto nos estabelecimentos da Microsoft nos Estados Unidos e em algumas lojas on-line da companhia. A Microsoft tinha convocado nesta segunda-feira os meios especializados para um ‘acontecimento especial’ sobre um assunto não especificado. As publicações especializadas em tecnologia como ‘CNET’ e ‘Mashable’ tinham especulado que podia se tratar do tablete e achavam que o anúncio seria feito depois do fechamento dos mercados. O anúncio precede em dois dias à chamada cúpula Windows Phone da Microsoft em San Francisco onde se espera que a companhia faça a estreia da próxima versão de seu sistema operacional Windows Phone OS. EFE Fonte Copyright Efe –

Todos os direitos de reprodução e representação são reservados para a Agência Efe.

Fonte

MVA – Microsoft Virtual Academy

Olá! Boa tarde!
Quer estudar para as provas de certificação Microsoft?! A própria Microsoft oferece alguns cursos gratuitos! É rápido e fácil de acessar!

Os materiais são bem introdutórios, mas já é uma ajuda, né?!

Quer acessar o MVA? Clique Aqui

Abraço!

UNION x UNION ALL

Muitas vezes vejo pessoas com dúvida sobre a diferença entre UNION e UNION ALL, apesar de ser simples a diferença.

Explicando de uma forma um pouco “grosseira”:

  • UNION realiza um DISTINCT entre os SELECTS, ou seja, os registros que tiverem informação repetida só apareceram uma vez no ResultSet
  • UNION ALL simplesmente une os SELECTS, ou seja, os registros que tiverem informação repetido apareceram no ResultSet quantas vezes eles existirem

Existem algumas regras para se usar o UNION e o UNION ALL (e são as mesmas):

  • Os ResultSet devem conter o mesmo número de colunas e devem ser do mesmo tipo (INT, NUMERIC, VARCHAR); caso contrário o SQL Server retornará um erro;
  • O nome das colunas deverá estar no primeiro SELECT e será atribuído as demais colunas;
  • A cláusula de ordenação ORDER BY só poderá ser usada após o último SELECT e ordenará todo o resultado que foi unido pelo UNION ou pelo UNION ALL; caso contrário, o SQL Server retornará um erro.

Dica de Perfomance: Se você precisa unir resultados que não podem se repetir e você conhece os resultados do SELECT e já sabem que eles não se repetem, então você deve usar o UNION ALL, pois ele não utilizará o DISTINCT entre os SELECTS o que causa um ganho de PERFOMANCE. Já se você usar o UNION o SQL Server utilizará um DISTINCT em cima de um resultado que não se repete, ou seja, consumirá recursos À toa.

Vamos ao exemplo prático:

–Declara variáveis de tabela para exemplo

DECLARE @tabela1 as TABLE(codigo int null, nome varchar(50) null)

DECLARE @tabela2 as TABLE(codigo int null, nome varchar(50) null)

 

–Insere dados na @tabela1

INSERT INTO @tabela1 VALUES

(1,‘nome1’),

(2,‘nome2’),

(3,‘nome3’),

(4,‘nome4’)

 

–Insere dados na @tabela2

INSERT INTO @tabela2 VALUES

(1,’nome1′),

(3,’nome3′),

(5,’nome5′),

(7,’nome7′)

 

–Exibe os campos da @tabela1

SELECT

                *

FROM

                @tabela1

–Exibe os campos da @tabela2    

SELECT

                *

FROM

                @tabela2

 

–Note que somente os registros do nome1 e nome3 se repetem nas tabelas

 

–Agora veja o resultado da união das duas consultas utilizando o UNION

–Os campos que possuem registros repetidos nas duas tabelas são exibidos apenas uma única vez

SELECT

                *

FROM

                @tabela1

UNION

SELECT

                *

FROM

                @tabela2

 

 

–Agora veja o resulta da união das duas consultas utilizando o UNION ALL

–Os campos que possuem registros repetidos nas duas tabelas são exibidos quantas vezes existirem nas consultas envolvidas

SELECT

                *

FROM

                @tabela1

UNION ALL

SELECT

                *

FROM

                @tabela2

 

 

 Analisando os planos de execução você pode ver porque o melhor é usar o UNION ALL no caso de você ter certeza de que os campos não vão se repetir, pois, neste caso, a consulta custa 22% a menos no UNION ALL por causa do DISTINCT (que equivale a 63% dos 35% gastos) do custo total  que é utilizado no UNION. Veja abaixo: 

Plano de Execução com UNION

 

 

Plano de Execução com UNION ALL

 

 Bom…por hoje é só. Espero que vocês tenham conseguido entender a diferença entre UNION e UNION ALL. Mais do que isso, que vocês tenham aprendido quando usar cada um deles!

Até o próximo post!