Material de Apoio – Agosto 2017


Boa tarde pessoal!

Salve, salve amantes de banco de dados, Tudo bem?

Este é mais um post da sessão Material de Apoio, sendo o terceiro no decorrer de 2017 e de número 153 no total desta sessão.

Já passamos da metade de 2017, que loucura isso, como a rotina do dia a dia não nos deixa perceber o quanto o tempo na para de correr. Falando justamente da correria da nossas vida, a relação de arquivos compartilhadas neste post poderá justamente lhe ajudar a economizar muito do seu tempo.

O post de hoje

Para aqueles que já acompanham o meu blog a um certo tempo, os posts dedicados a sessão Material de Apoio, possuem o objetivo de compartilhar o conhecimento de recursos, funcionalidades e procedimentos que podemos realizar no Microsoft SQL Server.

Hoje não será diferente, estou trazendo alguns dos mais recentes scripts  catalogados nos últimos meses, que atualmente estão compondo a minha galeria de códigos formada ao longo dos anos de trabalho como DBA, e hoje principalmente como Professor de Banco de Dados.

Neste post você vai encontrar arquivos relacionados com os seguintes temas:

  • Cláusula Values;
  • Comando Distinct;
  • Comando Select;
  • Comando Top;
  • CTE Recursiva para geração de sequência de datas;
  • CTE Recursiva para geração de sequência numérica de CEPs;
  • Extended Events;
  • Função Format;
  • Função PARSE;
  • Funções de Ranking – Row_Number;
  • Monitoramento de senhas;
  • Operador Cross Apply;
  • Operador Outer Appy;
  • Recursos bloqueados;
  • SPDIDs de Conexões;
  • SPIDs de usuários; e
  • User Defined Function para cálculo de anos em colunas computadas.

Tenho a certeza que este conteúdo poderá lhe ajudar muito em seus atividades profissionais e acadêmicas, fique a vontade para copiar, editar, compartilhar e distribuir estes arquivos com seus contatos.

Material de Apoio

A seguir apresento a relação de scripts selecionados:

 

 

 

 

 

 

 

 

 

Por questões de compatibilidade com a plataforma WordPress.com, todos os arquivos estão renomeados com a extensão .doc ao final do seu respectivo nome, sendo assim, após o download torna-se necessário remover esta extensão, mantendo somente a extensão padrão .sql.

Nota: Todos os arquivos disponibilizados foram obtidos ou criados com autorização de seus autores, sendo estes, passíveis de direitos autorais.

Links

Caso você queira acessar os posts anteriores da sessão, não perca tempo utilize os links listados abaixo:

Agradecimento

Quero agradecer imensamente a sua visita, espero lhe encontrar muitas vezes no decorrer deste ano em meu blog.

Não deixe de acessar os outros posts das demais sessões, e o próximo post desta sessão será publicado no mês de Novembro, até lá continue curtindo sua vida e compartilhando suas experiência.

Um forte abraço.

#13 – Para que serve


Muito boa noite galera, tudo bem?

Noite de sábado, temperatura agradável, galera curtindo uma pizza, balada entre outras coisas e eu estou aqui para compartilhar com você mais um post da minha sessão Para que serve, hoje o post de número 13. Você esta pensando, post de número 13 não é nada muito “ospicioso” como diária um personagem de novela (kkkkk).

Que nada vamos em frente não se preocupe com este número, tenho a certeza que este post será muito legal e apresentará informações de alto astral relacionada ao novo Microsoft SQL Server 2016.

Como você já deve ter percebido os posts relacionados a esta sessão tem o objetivo de apresentar ou demonstrar como  códigos de exemplo, aplicativos, utilitários, enfim recursos relacionados diretamente á banco de dados ou gerenciadores de bancos de dados podem ser utilizados como uma possível solução de problemas, bem como, orientar na sua forma de utilização.

Após esta tradicional saudação, chegou a hora de falar sobre o #13 – Para que serve de hoje, tenho a certeza que você vai gostar.

No post de hoje, vou a destacar uma das mais aguardados melhorias relacionadas ao SQL Server, estou me referindo a capacidade de consultor os histogramas de estatísticas de processamento de forma programada, isso mesmo, agora a partir da nova atualização cumulativa do SQL Server 2016 SP1, conhecida como Cumulative Update 2, temos duas novas DMF – Dynamic Management Function – Função de Gerenciamento Dinâmico que nos permitem de forma direta através do uso do comando Select obter informações sobre os histogramas e dados estatísticos.

Vou fazer um pequeno suspense, não vou revelar o nome de ambas as DMFs, somente no decorrer deste post você vai conhece-las.

Muito bem, após deixar este gostinho de quero mais, chegou a hora de conhecer estas novas funcionalidades e ver como podemos aplicar isso no nosso ambiente.

Como aqui o #13 – Para que serve – Uma nova e mais fácil maneira de obter informações sobre o histograma de estatísticas no Microsoft SQL Server 2016 SP1 –

Introdução

Quando se referimos a estatísticas de bancos de dados, estatísticas de processamento ou estatísticas de consumo de operadores do plano de execução, estamos na verdade se referindo ao bom e velho conceito de estatísticas, o qual devemos voltar no tempo para entender melhor se realmente quisermos saber a importância deste assunto, para este post este não é o foco, na verdade o que eu quero é mostrar que a partir da nova atualização cumulativa aplicada para o Service Pack 1 do SQL Server 2016 os times de engenheiros e desenvolvedores do SQL Server introduziram no produto duas novas DMF denominadas sys.dm_db_stats_histogram e sys.dm_db_stats_properties, onde através do uso destas novas DMFs podemos obter todas as informações relacionadas as estatísticas de processamento de nossas querys e principalmente o histograma de maneira mais rápida, fácil e principalmente legível, pois particularmente falando ler o histograma através do comando DBCC Show_Statistics não era nada fácil(kkkkk).

Vamos conhecer um pouco mais sobre cada DMF para entender melhor seu funcionamento:

sys.dm_db_stats_histogram: Retorna o histograma de estatísticas para o objeto de banco de dados especificado (tabela ou exibição indexada) no atual SQL Server banco de dados. Semelhante ao DBCC SHOW_STATISTICS WITH HISTOGRAM.

Ao executar esta nova DMF o Microsoft SQL Server 2016 apresentará uma tabela de resultado contendo o seguinte conjunto de colunas, conforme a Tabela 1 ilustra:

Nome da coluna

Column name
Tipo de dados Description
object_id int ID do objeto (tabela ou exibição indexada) para o qual as propriedades do objeto de estatísticas serão retornadas.
stats_id int ID do objeto de estatísticas. É exclusiva na tabela ou exibição indexada. Para obter mais informações, veja sys.stats.
step_number int O número da etapa do histograma.
range_high_key sql_variant Valor da coluna associada superior de uma etapa do histograma. O valor da coluna também será denominado um valor de chave.
range_rows real Número estimado de linhas cujo valor de coluna fica dentro de uma etapa do histograma, excluindo-se o limite superior.
equal_rows real Número estimado de linhas cujo valor de coluna é igual ao limite superior da etapa do histograma.
distict_range_rows bigint Número estimado de linhas com um valor de coluna distinto dentro de uma etapa do histograma, excluindo-se o limite superior.
average_range_rows real Número médio de linhas com valores de colunas duplicados em uma etapa de histograma, exceto o limite superior (RANGE_ROWS / DISTINCT_RANGE_ROWS para DISTINCT_RANGE_ROWS > 0).

sys.dm_db_stats_properties: Retorna propriedades de estatísticas para o objeto de banco de dados especificado (tabela ou exibição indexada) no banco de dados do SQL Server atual. Para tabelas particionadas, consulte a DMF sys.dm_db_incremental_stats_properties.

Ao executar esta nova DMF o Microsoft SQL Server 2016 apresentará uma tabela de resultado contendo o seguinte conjunto de colunas, conforme a Tabela 2 ilustra:

Nome da coluna Tipo de dados Description
object_id int ID do objeto (tabela ou exibição indexada) para o qual as propriedades do objeto de estatísticas serão retornadas.
stats_id int ID do objeto de estatísticas. É exclusiva na tabela ou exibição indexada. Para obter mais informações, veja sys.stats.
last_updated datetime2 Data e hora da última atualização do objeto de estatísticas.
rows bigint O número total de linhas da tabela ou exibição indexada na última atualização das estatísticas. Se as estatísticas forem filtradas ou corresponderem a um índice filtrado, o número de linhas talvez seja menor do que o número de linhas na tabela.
rows_sampled bigint O número total de linhas amostradas para cálculos de estatísticas.
etapas int O número de etapas no histograma. Para obter mais informações, veja DBCC SHOW_STATISTICS.
unfiltered_rows bigint O número total de linhas da tabela antes da aplicação da expressão de filtro (para estatísticas filtradas). Se as estatísticas não forem filtradas, unfiltered_rows será igual ao valor retornado na coluna de linhas.
modification_counter bigint Número total de modificações da coluna de estatísticas principal (a coluna em que o histograma é criado) desde que as últimas estatísticas de tempo foram atualizadas.

Essa coluna não mantém informações para tabelas com otimização de memória.

Agora que o segredo foi revelado, podemos começar a pensar na maneira que estas novas DMFs podem ser utilizadas, para tal vamos fazer uso do banco de dados analítico: AdventureworksDW2016CTP3 disponível para download através do link: http://www.microsoft.com/en-us/download/details.aspx?id=49502

Utilizando as novas DMFs

Seguindo em frente vamos começar nossa prática, para tal a primeira coisa a fazer é executar o bloco de código 1 declarado abaixo, antes clique no botão Include Actual Execution Plan em seu Management Studio, pois vamos realizar uma análise após a execução.

— Bloco de Código 1 —

Figura 1 – Instrução select declarada para o bloco de código 1.

Após a execução deste bloco de código obtemos o seguinte conjunto de dados relacionados ao operador Clustered Index Scan, conforme a Figura 2 apresentada abaixo:

Figura 2 – Dados relacionadas ao operador Clustered Index Scan.

Note que estou destacando na figura os dados referentes aos seguintes elementos:

  • Number of Rows Read;
  • Actual Number of Rows;
  • Estimated Number of Rows; e
  • Estimated Number of Rows to be Read.

Você pode estar se perguntando, o porque o Junior Galvão acabou destacados estes valores na Figura 2? A resposta é muito simples, uma das maneiras para tentar entender o comportamento do SQL Server no processamento de seus operadores e procurar ter uma ideia de estatísticas de processamento é justamente através da leitura e entendimento destes quatro conjunto de dados, o que posso dizer que não é a melhor forma para se encontrar informações sobre processamento e estatísticas.

Agora imagine que todas as vezes que você desejar obter informações sobre as estatísticas de processamento e como elas estão armazenadas e seus status, pois bem, é justamente neste ponto que agora no novo SQL Server 2016 SP1 CU 2 você terá facilmente a capacidade de fazer isso acontecer, para tal vamos executar o bloco de código 2 fazendo uso da nova DMF, sys.dm_db_status_histogram.

— Bloco de Código 2 —

Figura 3 – Bloco de código 2.

Observe que estamos fazendo uso da nova DMF sys.dm_db_status_histogram e neste momento nosso Management Studio deverá ter retornado um conjunto de linhas conforme a Figura 4 abaixo ilustra:

Figura 4 – Conjunto de dados estatísticas referentes ao processamento do bloco de código 2.

Ao analisarmos a Figura 4 podemos notar facilmente o conjunto de linhas de retornado contendo todas as informações relacionadas ao histograma da estatísticas de número 2 para a tabela [dbo].[FactResellerSales]. Tenho a certeza que você tão surpreso quanto eu quando executei pela primeira vez este mesmo bloco de código, realmente é assustador a facilidade que temos agora em entender o histograma.

Sensacional, mas como o SQL Server consegui apresentar estes dados desta maneira? Como de costume a resposta é simples, através da capacidade de utilizar em tempo de execução uma Table Valued Function denominada DM_DB_STATS_HISTOGRAM, ou seja, uma função que armazena valores em uma determinada tabela utilizada especificamente para esta nova DMF, a comprovação disso esta na Figura 5 que ilustra o plano de execução utilizado para o processamento do bloco de código 2.

Figura 5 – Plano de execução gerado para o processamento do bloco de código 2.

Continuando nossa jornada, o próximo passo é fazer uso da outra DMF, no caso a sys.dm_db_stats_properties, onde a qual vamos nos permitir obter o mesmo conjunto de valores referente ao cabeçalho da estatística o mesmo realizado através do comando DBCC SHOW_STATISTICS com a opção WITH STATS_HEADER.

Vamos então executar o bloco de código 3 apresentado a seguir:

Figura 7 – Bloco de código 3.

E qual será o resultado obtido após o processamento do bloco de código 3? A resposta é apresentada na Figura 7 a seguir:

Figura 7 – Resultado do processamento do bloco de código 3.

Show de bola, temos exatamente o mesmo conjunto de dados retornados pela DMF sys.dm_db_stats_properties da mesma forma que teríamos se estivéssemos utilizando do bom e velho DBCC SHOW_STATISTICS, não é realmente fantástico, só de imaginar a capacidade de possibilidades que teremos de utilizar estes dados a partir de agora realmente é algo surreal.

Da mesma forma que o SQL Server 2016 SP1 CU2 utiliza uma Table Valued Function para armazenar e apresentar os consumidos e coletados pelo processamento da sys.dm_db_status_histogram, também é utilizada uma outra Table Valued Function para o processamento da sys.dm_db_stats_properties denominada DM_DB_STATS_PROPERTIES.

Para finalizar nossa brincadeira e mostrar como estas novas funcionalidades podem nos ajudar, vamos utilizar o bloco de código 4 para através dele conseguir especificar uma determinada range_key existe em nossas estatísticas. Poxa vida especificar em um comando select qual determinada faixa de valores estatísticas nós queremos obter dados realmente é acima do que estávamos pensando, por incrível que isso possa parecer, é totalmente possível de ser feito a partir de agora.

— Bloco de Código 4 —

Figura 8 – Retorno de dados referentes ao filtro da faixa de valores.

Putz, que coisa louco, meu deus, temos com base no bloco de código 4 a comprovação que podemos através do uso de outras DMFs inline retornado dados estatísticos com base em filtros ou predicados declarados na cláusula where existente na linha 26 onde, a coluna sh.range_high_key é justamente uma coluna pertencente a nova DMF sys.dm_db_stats_histogram.

Que loucura isso, fora de série esta nova capacidade do SQL Server, fantástico, inimaginável, fora do comum o que o time de engenheiros do SQL Server fizeram desta vez, show.

Referências

https://msdn.microsoft.com/library/mt794645.aspx

https://blogs.msdn.microsoft.com/sql_server_team/easy-way-to-get-statistics-histogram-programmatically/

https://support.microsoft.com/en-us/help/4013106/cumulative-update-2-for-sql-server-2016-sp1

http://msdn.microsoft.com/library/jj553546.aspx

http://msdn.microsoft.com/library/ms174384.aspx

https://msdn.microsoft.com/pt-br/library/mt761751.aspx

https://msdn.microsoft.com/pt-br/library/ms177623.aspx

Links

Caso você ainda não tenha acessado os posts anteriores desta sessão, fique tranquilo é fácil e rápido, basta selecionar um dos links apresentados a seguir:

https://pedrogalvaojunior.wordpress.com/2017/01/23/12-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2016/12/16/11-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2016/11/15/10-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2016/10/08/09-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2016/08/06/07-para-que-serve/

Conclusão

A maneira como nossos dados estão constantemente sendo processados é algo que a cada dia um DBA ou profissional de banco de dados se pergunta. Saber em qual momento uma determinada query, transação ou simplesmente um comando select pode ocasionar algo tipo de impacto em nosso ambiente ainda é mais preocupante. Foi justamente pensando nisso que a Microsoft e seu time de profissionais que trabalham com o SQL Server buscaram responder a partir da disponibilidade das duas novas DMFs: sys.dm_db_stats_histogram e sys.dm_db_stats_properties recursos adicionados na versão 2016 SP1 e disponível também para próximas versão do SQL Server, dentre elas a SQL Server vNext.
Esta nova maneira de acessar e consultar os dados coletados e armazenados no histograma poderá ajudar em muito os profissionais de banco de dados e desenvolvedores a entender como seus estatísticas de processamento de dados estão sendo afetadas com base nos processos de manipulação.
Neste post você pode mais uma vez observar que o Microsoft SQL Server esta em constante evolução, um dos produtos mais prestigiados pela Microsoft, buscando sempre trazer melhorais e inovações, algo de extrema importância para qualquer profissional que trabalha com esta tecnologia.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Nos encontramos em breve, até lá…..

Short Scripts – Dezembro 2016


Buenas tardes….. Comunidade.

Hoje um dia mais que especial na minha vida e da minha família, meu pai Pedro Galvão esta completando 60 anos de vida, meu deus, como o tempo nos supreende com a sua velocidade.

Quero aproveitar este post para agradeço por este privilégio de poder conviver com uma pessoa tão integra, humilde, trabalhadora, honesta, enfim existem milhares de adjetivos para definir o que meu pai e sua excência em pessoa representa.

O post de hoje

Falando do post de hoje, este é um último post dedicado a sessão Short Scripts no ano de 2016, mas com certeza em 2017 vai estar retornando com toda a força.

Como de costume, e não poderia ser diferente, estamos no final do ano, próximos ao Natal, momento de festa e troca de presentes, lógicamente vou deixar o meu presentinho para vocês, compartilhando os últimos scripts adquiridos neste ano, relacionados aos seguintes assuntos:

  • Calendário anual de feriados;
  • Conversão de Binários para String;
  • CTE e CTE Recursiva;
  • Funções;
  • Extended Stored Procedure XP_ServiceControl;
  • MaxRecursion;
  • Union e Union All; e
  • Monitoramento de Serviços.

Short Scripts

A seguir apresento a relação de Short Scripts de hoje:

— Short Script 1 – Monitorando os serviços do SQL Server através da Extended Stored Procedure – XP_ServiceControl

Set NoCount On
CREATE TABLE #ServicesStatus
(
myid int identity(1,1),
serverName nvarchar(100) default @@serverName,
serviceName varchar(100),
Status varchar(50),
checkdatetime datetime default (getdate())
)
INSERT #ServicesStatus (Status)
EXEC xp_servicecontrol N’QUERYSTATE’,N’MSSQLServer’
update #ServicesStatus set serviceName = ‘MSSQLServer’ where myid = @@identity
INSERT #ServicesStatus (Status)
EXEC xp_servicecontrol N’QUERYSTATE’,N’SQLServerAGENT’
update #ServicesStatus set serviceName = ‘SQLServerAGENT’ where myid = @@identity
INSERT #ServicesStatus (Status)
EXEC xp_servicecontrol N’QUERYSTATE’,N’msdtc’;
update #ServicesStatus set serviceName = ‘msdtc’ where myid = @@identity;
INSERT #ServicesStatus (Status)
EXEC xp_servicecontrol N’QUERYSTATE’,N’sqlbrowser’
update #ServicesStatus set serviceName = ‘sqlbrowser’ where myid = @@identity
Select * from #ServicesStatus
— Short Script 2 – Realizando a conversão de Binário para String e String para Binário —
— Declarando uma chave legível —
DECLARE @chave  VARCHAR(MAX) =’quechavemalfeita’
— Convertendo para Binário —
DECLARE @dadosBinary VARBINARY(MAX) = CONVERT(VARBINARY(MAX),@chave,0)
SELECT @chave,@dadosBinary
— Observando as diferenças —
SELECT CONVERT(VARCHAR(MAX),@dadosBinary,0) –o Tipo 0 tranforma em texto legivelSELECT CONVERT(VARCHAR(MAX),@dadosBinary,1) — transforma o valor BINARY EM VALOR VARCHAR DEIXANDO O MESMO CONTEUDO

SELECT CONVERT(VARCHAR(MAX),@dadosBinary,2)– transforma o valor BINARY EM VALOR VARCHAR RETIRANDO O 0x NO INICIO
Go

— Short Script 3 – Criando um calendário anual para feriados —
CREATE SCHEMA Calendar
Go
CREATE FUNCTION Calendar.Computus (@Y INT)
RETURNS DATETIME
AS
BEGIN
DECLARE @a INT, @b INT, @c INT, @d INT, @e INT, @f INT, @g INT, @h INT, @i INT, @k INT, @L INT, @m INT
SET @a = @Y % 19
SET @b = @Y / 100
SET @c = @Y % 100
SET @d = @b / 4
SET @e = @b % 4
SET @f = (@b + 8) / 25
SET @g = (@b – @f + 1) / 3
SET @h = (19 * @a + @b – @d – @g + 15) % 30
SET @i = @c / 4
SET @k = @c % 4
SET @L = (32 + 2 * @e + 2 * @i – @h – @k) % 7
SET @m = (@a + 11 * @h + 22 * @L) / 451
RETURN(DATEADD(month, ((@h + @L – 7 * @m + 114) / 31)-1, cast(cast(@Y AS VARCHAR) AS Datetime)) + ((@h + @L – 7 * @m + 114) % 31))
END
GO
CREATE TABLE Calendar.[Calendar] (
[Date] datetime NOT NULL,
[Year] int NOT NULL,
[Quarter] int NOT NULL,
[Month] int NOT NULL,
[Week] int NOT NULL,
[Day] int NOT NULL,
[DayOfYear] int NOT NULL,
[Weekday] int NOT NULL,
[Fiscal_Year] int NOT NULL,
[Fiscal_Quarter] int NOT NULL,
[Fiscal_Month] int NOT NULL,
[KindOfDay] varchar(10) NOT NULL,
[Description] varchar(50) NULL,
PRIMARY KEY CLUSTERED ([Date])
)
GO
ALTER TABLE Calendar.[Calendar]
ADD CONSTRAINT [Calendar_ck] CHECK (  ([Year] > 1900)
AND ([Quarter] BETWEEN 1 AND 4)
AND ([Month] BETWEEN 1 AND 12)
AND ([Week]  BETWEEN 1 AND 53)
AND ([Day] BETWEEN 1 AND 31)
AND ([DayOfYear] BETWEEN 1 AND 366)
AND ([Weekday] BETWEEN 1 AND 7)
AND ([Fiscal_Year] > 1900)
AND ([Fiscal_Quarter] BETWEEN 1 AND 4)
AND ([Fiscal_Month] BETWEEN 1 AND 12)
AND ([KindOfDay] IN (‘HOLIDAY’, ‘SATURDAY’, ‘SUNDAY’, ‘BANKDAY’)))
GO
SET DATEFIRST 1;
WITH Dates(Date)
AS
(
SELECT cast(‘1999’ AS DateTime) Date
UNION ALL
SELECT (Date + 1) AS Date
FROM Dates
WHERE
Date < cast(‘2021’ AS DateTime) -1
),
DatesAndThursdayInWeek(Date, Thursday)
AS
(
SELECT
Date,
CASE DATEPART(weekday,Date)
WHEN 1 THEN Date + 3
WHEN 2 THEN Date + 2
WHEN 3 THEN Date + 1
WHEN 4 THEN Date
WHEN 5 THEN Date – 1
WHEN 6 THEN Date – 2
WHEN 7 THEN Date – 3
END AS Thursday
FROM Dates
),
Weeks(Week, Thursday)
AS
(
SELECT ROW_NUMBER() OVER(partition by year(Date) order by Date) Week,
Thursday
FROM DatesAndThursdayInWeek
WHERE DATEPART(weekday,Date) = 4
)
INSERT INTO Auxiliary.Calendar
SELECT
d.Date,
YEAR(d.Date) AS Year,
DATEPART(Quarter, d.Date) AS Quarter,
MONTH(d.Date) AS Month,
w.Week,
DAY(d.Date) AS Day,
DATEPART(DayOfYear, d.Date) AS DayOfYear,
DATEPART(Weekday, d.Date) AS Weekday,
YEAR(d.Date) AS Fiscal_Year,
DATEPART(Quarter, d.Date) AS Fiscal_Quarter,
MONTH(d.Date) AS Fiscal_Month,
CASE
WHEN (DATEPART(DayOfYear, d.Date) = 1)          — New Year’s Day
OR (d.Date = Auxiliary.Computus(YEAR(Date))-7)  — Palm Sunday
OR (d.Date = Auxiliary.Computus(YEAR(Date))-3)  — Maundy Thursday
OR (d.Date = Auxiliary.Computus(YEAR(Date))-2)  — Good Friday
OR (d.Date = Auxiliary.Computus(YEAR(Date)))    — Easter Sunday
OR (d.Date = Auxiliary.Computus(YEAR(Date))+39) — Ascension Day
OR (d.Date = Auxiliary.Computus(YEAR(Date))+49) — Pentecost
OR (d.Date = Auxiliary.Computus(YEAR(Date))+50) — Whitmonday
OR (MONTH(d.Date) = 5 AND DAY(d.Date) = 1)      — Labour day
OR (MONTH(d.Date) = 5 AND DAY(d.Date) = 17)     — Constitution day
OR (MONTH(d.Date) = 12 AND DAY(d.Date) = 25)    — Cristmas day
OR (MONTH(d.Date) = 12 AND DAY(d.Date) = 26)    — Boxing day
THEN ‘HOLIDAY’
WHEN DATEPART(Weekday, d.Date) = 6 THEN ‘SATURDAY’
WHEN DATEPART(Weekday, d.Date) = 7 THEN ‘SUNDAY’
ELSE ‘BANKDAY’
END KindOfDay,
CASE
WHEN (DATEPART(DayOfYear, d.Date) = 1)            THEN ‘New Year”s Day’
WHEN (d.Date = Auxiliary.Computus(YEAR(Date))-7)  THEN ‘Palm Sunday’
WHEN (d.Date = Auxiliary.Computus(YEAR(Date))-3)  THEN ‘Maundy Thursday’
WHEN (d.Date = Auxiliary.Computus(YEAR(Date))-2)  THEN ‘Good Friday’
WHEN (d.Date = Auxiliary.Computus(YEAR(Date)))    THEN ‘Easter Sunday’
WHEN (d.Date = Auxiliary.Computus(YEAR(Date))+39) THEN ‘Ascension Day’
WHEN (d.Date = Auxiliary.Computus(YEAR(Date))+49) THEN ‘Pentecost’
WHEN (d.Date = Auxiliary.Computus(YEAR(Date))+50) THEN ‘Whitmonday’
WHEN (MONTH(d.Date) = 5 AND DAY(d.Date) = 1)      THEN ‘Labour day’
WHEN (MONTH(d.Date) = 5 AND DAY(d.Date) = 17)     THEN ‘Constitution day’
WHEN (MONTH(d.Date) = 12 AND DAY(d.Date) = 25)    THEN ‘Cristmas day’
WHEN (MONTH(d.Date) = 12 AND DAY(d.Date) = 26)    THEN ‘Boxing day’
END Description
FROM DatesAndThursdayInWeek d
inner join Weeks w
on d.Thursday = w.Thursday
OPTION(MAXRECURSION 0)
GO
CREATE FUNCTION Auxiliary.Numbers (@AFrom INT, @ATo INT, @AIncrement INT)
RETURNS @RetNumbers TABLE
([Number] int PRIMARY KEY NOT NULL)
AS
BEGIN
WITH Numbers(n)
AS
(
SELECT @AFrom AS n
UNION ALL
SELECT (n + @AIncrement) AS n
FROM Numbers
WHERE
n < @ATo
)
INSERT @RetNumbers
SELECT n from Numbers
OPTION(MAXRECURSION 0)
RETURN;
END
GO
CREATE FUNCTION Auxiliary.iNumbers( @AFrom INT, @ATo INT, @AIncrement INT)
RETURNS TABLE
AS
RETURN( WITH Numbers(n)
AS
(SELECT @AFrom AS n
UNION ALL
SELECT (n + @AIncrement) AS n
FROM Numbers
WHERE
n < @ATo)
SELECT n AS Number from Numbers
)
GO

Links

Caso você queira acessar os últimos posts desta sessão, não perca tempo acesse os links listados abaixo:

Agradecimento

Mais uma vez obrigado por sua visita, um forte abraço…

Feliz Natal com muita saúde, paz, alegria e esperança. Que 2017 você possa brilhar ainda mais e estar junto com a comunidade.

Microsoft SQL Server 2016 e String_Split(), agora ficou fácil dividir uma string.


Fala galera, boa tarde, segunda – feira, eita dia complicado, começo de semana é tenso, pois saber que mais um final de semana passou voando é triste. Vamos em frente e pensar que mais um final de semana está chegando, é bem melhor.

Seguindo a onda de informações, anúncios, posts, entre outras formas de divulgação sobre o Microsoft SQL Server 2016, hoje vou destacar mais um pouco no meu blog sobre esta nova versão e destacar mais uma das suas novidades, estou me referindo a nova Table Value Function String_Split(). Algo que realmente era muito pedido pelos desenvolvedores e que a Microsoft demorou um pouco para reconhecer a sua importância, mas na versão 2016 ela está presente e será muito útil.

 

A String_Split()

Pode-se dizer que é uma daquelas funções desejadas por todos os profissionais que trabalham com desenvolvimento e necessitam em algum momento realizar o chamado split de uma string. Se você não sabe ou conhece este termo, split pode ser entendido como fatiar, dividir, cortar, quebrar em pedaços.

Fazendo uma analogia, a string_split() vai fazer exatamente isso com uma string, transformando a mesma em pequenas outras strings (substrings ou partes de uma string).

Funcionalidade ou capacidade considerado por muitos como algo realmente complexo se der feito por um SGBD – Sistema Gerenciador de Banco de Dados, ainda mais para o SQL Server se pensarmos que até a versão 2014 tínhamos a necessidade de customizar este tipo de necessidade.

Mas que para nossa alegria a Microsoft introduziu este recurso na versão RC0 sinal que provavelmente e o que tudo indica a mesma vai fazer parte da versão final do SQL Server 2016.

 

Compatibilidade

Por se tratar de uma nova funcionalidade, até o presente momento a documentação oficial da Microsoft indica que esta função é compatível com a versões:

  • Microsoft SQL Server 2016; e
  • Azure Database.

As versões Azure SQL Data Warehouse e Parallel Data Warehouse até o momento não estão na lista de produtos compatíveis com a esta nova função.

Observação: Um detalhe muito importante é a necessidade do nível de compatibilidade do banco de dados estar definido na versão 130, sendo este o nível do SQL Server 2016.

 

Sua importância. O porquê ela pode ajudar

A String_Split() vem para preencher uma lacuna muito grande deixada pelo tipo de desenvolvimento e engenheiros da Microsoft desde a versão 2008 e 2012, onde novas funções para se trabalhar com string foram adicionadas no produto.

Sua importância vai muito além da capacidade técnica de permitir que uma string seja dividida em pequenas partes e posteriormente armazenada em uma tabela, variável ou função, ela vai com certeza flexibilidade e facilitar em muito a maneira com que os dados podem ser tratados e reconhecidos pelo SQL Server o que poderá permitir a criação de novos padrões de reconhecimento de caracteres.

Uma das grandes vantagens de se utilizar a String_Split() está relacionada com a uma simples sintaxe, onde requer basicamente dois parâmetros.

 

Como utilizar a String_Split()

Criada para ser utilizada de maneira rápida e simples, a String_split é composta pode dois parâmetros string compatíveis com os tipos de dados: (nvarcharvarcharnchar ou char) para a string que desejamos supostamente dividir em conjunto com o caractere reconhecido como “divisor” ou “separador”, que também deve ser informado em um tipo de string compatível com os tipos de dados: nvarchar(1)varchar(1)nchar(1) ou char(1)).

Outra característica muito interessante desta função é a maneira que os dados são apresentados e retornados para usuário, onde podemos ter o retorno do split da string em uma coluna com diversas linhas representando os fragmentos “pedaços” ou “partes” da string, como também um valor caractere no tipo de dados nchar ou nvarchar de acordo com o tipo de dado utilizado, respeitando o tamanho do dado identificado no momento da fragmentação da string. Caso não seja reconhecido o tipo de dados original da string, o resultado da sua fragmentação será retornado com o tipo de dados varchar.

Exemplos

A seguir você vai poder encontrar alguns exemplos de como podemos fazer uso da função String_Split(). Vale ressaltar que esta função se encontra disponível a partir da versão RC0, requerendo a configuração o nível de compatibilidade para o número 130.

Alguns dos exemplos apresentados aqui foram elaborados e executados no banco de dados de exemplo AdventureWorks2016 CTP3, caso venha tenha interesse em realizar o download desta sample database, utilize o link: https://www.microsoft.com/en-us/download/details.aspx?id=49502

Outro detalhe importante a ser destacado é o resultado apresentado para cada exemplo ilustrado a seguir, por padrão o SQL Server gera uma coluna chamada value contendo a lista de valores fragmentados após o processo de split da string.

 

 

— Exemplo 1 – Separando de forma simples uma string –

SELECT *

FROM STRING_SPLIT(‘Junior,Galvão,MVP,SQL Server’,’,’)

Go

 

Resultado

value
Junior
Galvão
MVP
SQL Server

 

— Exemplo 2 – Fazendo uso de variáveis como parâmetros de entrada de valores –

DECLARE @string VARCHAR(100) = ‘Microsoft,SQL Server,2016,RC0′,

@separador CHAR(1) =’,’

 

SELECT *

FROM STRING_SPLIT(@string,@separador)

Go

 

Resultado

value
Microsoft
SQL Server
2016
RC0

 

— Exemplo 3 – Armazenando o resultado da divisão de uma string em uma nova tabela –

DECLARE @string VARCHAR(100) = ‘Microsoft,SQL Server,2016,RC0′,

@separador CHAR(1) =’,’

 

SELECT * INTO #SplitTable

FROM STRING_SPLIT(@string,@separador)

GO

 

— Visualizando a estrutura da tabela —

sp_Columns #SplitTable

Go

 

— Consultando os dados da tabela —

Select * from #SplitTable

Go

 

Após executar a system stored procedure sp_columns podemos notar que o tamanho e tipo de dados da coluna value criada através do select…into foi definido como Varchar() sendo este o tipo de dados padrão utilizado pela String_Split() para garantir compatibilidade no armazenamento e apresentação de dados oriundos de uma outra tabela.

 

— Exemplo 4 – Apresentando a mensagem quando o separador de string for definido com mais de um caracter —

DECLARE @string VARCHAR(100) = ‘pedrogalvaojunior#@gmail#@com’,

@separador CHAR(2) =’#@’

 

SELECT * FROM STRING_SPLIT(@string,@separador)

Go

 

Como pode ser observado o Microsoft SQL Server 2016 vai lançar e apresentar uma mensagem de erro com o código 214 informando que a quantidade de caracteres ou melhor dizendo que o tamanho utilizado para o parâmetro separador foi definido acima de um caractere, sendo que, este parâmetro só identifica e reconhece um único caractere.

Resultado

Msg 214, Level 16, State 11, Line 3

Procedure expects parameter ‘separator’ of type ‘nchar(1)/nvarchar(1)’.

 

— Exemplo 5 – Apresentando o comportamento da String_Split() quando um parâmetro apresenta valor nulo –

SELECT * FROM STRING_SPLIT(‘pedrogalvaojunior,wordpress,com’,NULL)

Go

 

Para este exemplo 5 o comportamento do SQL Server 2016 é exatamente o mesmo do exemplo 4, onde será apresentanda uma mensagem de erro informando que o tamanho informado no parâmetro separado, foi definido acima de um caractere.

Resultado

Msg 214, Level 16, State 11, Line 3

Procedure expects parameter ‘separator’ of type ‘nchar(1)/nvarchar(1)’.

 

— Exemplo 6 – Realizando o split de uma string com base na junção de uma tabela com a função String_Split() –

— Criando a tabela Split —

Create Table Split

( SplitId INT IDENTITY (1,1) NOT NULL,

SplitValue1 NVARCHAR(50),

SplitValue2 NVARCHAR(50))

GO

 

— Inserindo linhas de registro —

INSERT INTO Split (SplitValue1, SplitValue2)

VALUES (‘Pedro’,’Galvão’),

(‘Junior’,’Galvão’),

(‘Antonio’,’Silva’),

(‘Chico’,’Bento’)

Go

 

— Realizando a Junção da Tabela Split com a função Split_String() —

Select SplitId, SplitValue1, SplitValue2, Value

From Split S Inner Join String_Split(‘Pedro,Antonio’,’,’) STS

On S.SplitValue1 = STS.Value

Go

 

Observe que o SQL Server realizou o split dos dados com base na junção e valores informados para a função e mesmo assim apresentou os dados dados de cada coluna que compõem a estrutura da tabela Split.

 

Resultado

SplitID SplitValue1 SplitValue2 Value
1 Pedro Galvão Pedro
3 Antonio Silva Antonio

 

— Exemplo 7 – Apresentando o resultado quando ambos os parâmetros vazios –

Select * from String_Split(‘ ‘,’,’)

Go

 

Após executa o select acima o SQL Server identificou que ambos os parâmetros encontra-se vazios, sem nenhum tipo de dado que permita fazer a identificação da string e do separador, sendo assim o resultado retornado será uma única linha de registro vazia.

 

Resultado

Value

 

— Exemplo 8 – Apresentando o comportamento da String_Split() quando o caracter do final da string é o mesmo utilizado como separador –

SELECT * FROM STRING_SPLIT(‘Conhecendo,SQL Server,2016,’,’,’)

Go

 

Este é um cenário bem interessante e pode ocorrer a qualquer momento, nesta situação o SQL Server 2016 vai trabalhar da mesma forma que os outros exemplos, analisando e identificando a string e posteriormente fazendo a fragmentação com base no caractere separador, mesmo que este seja um caractere utilizado no final da string.

Note que que criada 4 linhas de registro sendo que a última não apresentará valores por será reconhecida e tratada como uma linha nula ou em branco.

Resultado

value
Conhecendo
SQL Server
2016

 

Legal, legal, acredito que agora ficou ainda mais fácil de entender e compreender como a String_Split() é fácil de ser utilizado e principalmente a maneira que os dados são apresentando e retornado para usuário. Desta forma, vou encerrar mais este artigo por aqui, quero também aproveitar para disponibilizar abaixo uma relação de links sobre os principais posts referentes ao SQL Server 2016 que estou desde 2015 publicando.

 


 

 

Links

Caso você não tenha acessado os posts anteriores dedicados ao Microsoft SQL Server 2016, não perca tempo e a oportunidade de conhecer mais sobre esta nova versão acessando os links abaixo:

https://pedrogalvaojunior.wordpress.com/2015/12/28/microsoft-sql-server-2016-e-json-uma-combinacao-bem-interessante-final/

https://pedrogalvaojunior.wordpress.com/2015/11/09/microsoft-sql-server-2016-e-json-uma-combinacao-bem-interessante-parte-i/

https://pedrogalvaojunior.wordpress.com/2015/10/02/conhecendo-o-live-query-statistics-no-microsoft-sql-server-2016/

https://pedrogalvaojunior.wordpress.com/2015/07/10/microsoft-sql-server-2016-lista-de-novidades-parte-i/

https://pedrogalvaojunior.wordpress.com/2015/07/16/microsoft-sql-server-2016-lista-de-novidades-parte-ii/

https://pedrogalvaojunior.wordpress.com/2015/07/30/microsoft-sql-server-2016-lista-de-novidades-final

 

Conheça o SQL Server 2016 RC0: Faça download da versão RC0 disponibilizada a poucos dias acessando: https://www.microsoft.com/en-us/evalcenter/evaluate-sql-server-2016. Acesse também da documentação oficial Microsoft sobre a String_Split(): https://msdn.microsoft.com/en-us/library/mt684588.aspx

 


 

Conclusão

Como você pode observar uma das mais esperadas funcionalidades foi adicionada ao SQL Server, a capacidade de fragmentar, dividir, fatiar uma string em pequenas partes ou substrings. Recurso mais que necessário e importante para qualquer desenvolver ou profissional de banco de dados que necessita analisar um texto “string” e através de um caractere denominado separador delimitar como pode ser gerada fragmentos deste texto.

A cada novo build liberado pela Microsoft podemos observar e notar o grande trabalho e esforço que esta sendo feito para transformar o Microsoft SQL Server 2016 na maior e principal versão do produto desde o grande salto dado em 2005 com o lançamento naquele momento da versão 2005.

Funções similares ao String_Split() estão sendo cada vez mais disponibilidades e adicionadas ao produto como forma de fazer com que o SQL Server se torne uma plataforma única de desenvolvimento, administração, armazenamento e gestão de banco de dados, isso representa uma grande evolução e atenção das equipes de desenvolvimento e engenheiros do produto em atender e satisfazer a comunidade técnica que se dedica a estudar e conhecer cada vez mais o SQL Server.

Acredito que os exemplos apresentados aqui conseguir mostrar a simplicidade de se trabalhar com esta nova funcionalidade, ilustrando sua simplicidade no uso e forma de obter os resultados.

Mais uma vez agradeço a sua atenção, seu interesse em visitar o meu blog, espero encontra-lo em outras oportunidades. Deixe seus comentários, críticas e sugestões.

Até a próxima.

Dica do Mês – Função Next Value For


Olá, galera, bom dia.

Estamos chegando ao final do primeiro mês de 2016, nossa janeiro já esta indo embora. Como eu havia prometido no início deste ano, dentro do possível vou tentar trazer novas sessões para o meu blog e hoje falo do lançamento ou melhor o retorno de uma delas que vou batizar de “Dica do Mês“, é isso mesmo, no final de cada vez vou trazer uma simples dica relacionada a algo que utililizei em minhas atividades profissionais e acadêmicas.

O objetivo desta sessão como seu próprio nome diz, é compartilhar com você leitor ou seguidor do meu blog, uma simples dica que poderá fazer toda diferença no seu dia-á-dia ou simplesmente mostrar como utilizar um determinado recurso, funcionalidade e produto existente no SQL Server.

Neste primeiro post, quero destacar uma função muito legal que foi introduzida no Microsoft SQL Server 2012 e que recentemente em diversas dúvidas nos fóruns brasileiros de SQL Server acabou sendo destaque como solução. Estou me referindo ao função Next Valeu For fazendo uma tradução ao pé da letra podemos dizer: Próximo Valor para.

 

Sobre Next Value For –  Função que possui a característica possibilitar a geração de uma sequência de números para uma objeto específico, neste caso, o objeto que refiro é Sequence Object, funcionalidade também introduzida a partir do Microsoft SQL Server 2012, em conjunto com diversas novidades relacionadas a geração de sequência de valores numéricos.

A Next Value For é reconhecida como uma função não-determinística, desta maneira o sua utilização é somente permitida em conjunto com o objeto sequence, sendo este responsável pela geração da sequência numérica repassada para a função.

 

Sintaxe – A função Next Value For possui uma forma de uso bastante simples, uma das suas particularidades é permitir o uso da função Over como opção para geração de valores dentro da sequência.

  • Exemplo da Sintaxe: NEXT VALUE FOR [ database_name . ] [ schema_name . ]  sequence_name
    [ OVER (<over_order_by_clause>) ]

 

Argumentos – Com base em sua sintaxe podemos identificar quatro argumentos que formam sua estrutura de código, sendo eles:

  • database_name – Representa o nome do banco de dados que possui o objeto sequence;
  • schema_name –  Representa o nome do schema que contém o objeto sequence;
  • sequence_name – Representa o nome do objeto sequence responsável em armazenar e garantir a sequência numérica
  • Over_order_by_clause – Determina a ordem de organização e apresentação dos valores das linhas dentro de uma faixa de valores gerados pelo objeto sequence.

 

Exemplos: Vou destacar algumas maneiras de como utilizar a função Next Value For:

— Exemplo 1- Utilizando a função Next Valeu For para mostrar dois valores em sequência —

CREATE SCHEMA Test;
GO

CREATE SEQUENCE Test.Contador
START WITH 1
INCREMENT BY 1 ;
GO

SELECT NEXT VALUE FOR Test.Contador AS FirstUse;
SELECT NEXT VALUE FOR Test.Contador AS SecondUse;

Go

 

— Exemplo 2 – Utilizando a função Next Valeu For em conjunto com variável —

DECLARE @var1 bigint = NEXT VALUE FOR Test.Contador
DECLARE @var2 bigint ;
DECLARE @var3 bigint ;

SET @var2 = NEXT VALUE FOR Test.Contador ;

SELECT @var3 = NEXT VALUE FOR Test.Contador;
SELECT @var1 AS myvar1, @var2 AS myvar2, @var3 AS myvar3 ;
GO

 

— Exemplo 3 – Utilizando a função Next Valeu For em conjunto com constraint Default —

CREATE TABLE Test.MyTable
(
IDColumn nvarchar(25) PRIMARY KEY,
name varchar(25) NOT NULL) ;
GO

CREATE SEQUENCE Test.CounterSeq
AS int
START WITH 1
INCREMENT BY 1 ;
GO

ALTER TABLE Test.MyTable
ADD DEFAULT N’AdvWorks_’ + CAST(NEXT VALUE FOR Test.CounterSeq AS NVARCHAR(20)) FOR IDColumn;
GO

INSERT Test.MyTable (name) VALUES (‘Junior’) ;
INSERT Test.MyTable (name) VALUES (‘Galvão’) ;

INSERT Test.MyTable (name) VALUES (‘SQL’) ;
INSERT Test.MyTable (name) VALUES (‘Server’) ;
SELECT * FROM Test.MyTable;
GO

 

— Exemplo 4 – Utilizando a função Next Value For com ranking windows function —

Use AdventureWorks2012

Go

SELECT NEXT VALUE FOR Test.Contador OVER (ORDER BY LastName) AS ListNumber,
FirstName, LastName
FROM Person.Contact ;
GO


 

Muito bem galera, é isso, este é o primeiro post da nova sessão Dica do Mês, simples, direto, rápido e prático, espero que você tenha gostado.

Não deixe de me visitar, amanhã vou retornar com mais uma novidade, uma nova sessão chamada “Para que serve“, por enquanto uma surpresa.

Mais uma vez obrigado, nos encontramos novamente nos próximos posts.

Até mais.

Microsoft SQL Server 2016 e JSON uma combinação bem interessante – Final


Bom dia, comunidade, segunda – feira, alias estamos na última semana de 2015, eita ano complicado, repleto de surpresas não tão boas, mas que esta se encerrando de forma razoável.

Para encerrar este ano, estou retornando com a parte final desta pequena série de posts dedicadas exclusivamente a esta novidade bastante útil e interessante que foi introduziada no Microsoft SQL Server 2016, como você pode observar no título estou me referindo ao suporte para uso do JSON em um ambiente rodando o SQL Server 2016.

Caso você não tenha acessado o post anterior sobre esta novidade ou outros posts dedicados ao Microsoft SQL Server 2016, não perca tempo e a oportunidade de conhecer mais sobre esta nova versão acessando os links abaixo:

https://pedrogalvaojunior.wordpress.com/2015/11/09/microsoft-sql-server-2016-e-json-uma-combinacao-bem-interessante-parte-i/

https://pedrogalvaojunior.wordpress.com/2015/07/10/microsoft-sql-server-2016-lista-de-novidades-parte-i/

https://pedrogalvaojunior.wordpress.com/2015/07/16/microsoft-sql-server-2016-lista-de-novidades-parte-ii/

https://pedrogalvaojunior.wordpress.com/2015/07/30/microsoft-sql-server-2016-lista-de-novidades-final/

 

Caso você já tenha acessado a primeira parte desta série, deverá ter observado que destaquei de forma bastante apronfudada como o JSON se tornou uma tecnologia tão presente e utilizada atualmente no desenvolvimento de software, além disso, apresentei um pouco da sua história e a visão do time de produto do SQL Server perante a comunidade.

Nesta segunda parte, conforme prometido vou destacar um pouco como podemos trabalhar com funções específicas do JSON e de que forma podemos criar uma indexação de dados existentes dentro do formato JSON.

Mais uma vez obrigado por sua visita, espero que este post possa ser útil e traga algum tipo de interesse e curiosidade em conhecer mais sobre o Microsoft SQL Server.

 

O JSON e suas funções

Como toda novidade, e isso também não poderia ser diferente para o JSON, os time de desenvolvimento e engenheiros do SQL Server, adicionaram neste nova versão um conjunto de funções internas exclusivas para se trabalhar com o JSON, sendo estas:

  • ISJSON: Definida e reconhecida como uma função JSON Text, a ISJOSON tem como finalidade verificar se o texto que esta sendo passado no formato JSON pode ser reconhecido como um tipo de dados NVARCHAR. Através desta função é possível podemos implementar restrições(constraints) em colunas com forma de verificação de dados. Importante destacar que esta função esta disponível a partir da versão SQL Server 2016 Community Technology Preview 3.2
  • JSON_Values: Definida e reconhecida como uma função JSON Text, a JSON_Value, possui um papel importante quando trabalhamos com dados JSON, que consiste basicamente na análise e extração de um possível valor escalar que representa um determinado caminho específico reconhecido pelo padrão JavaScript, como forma de obter e reconhecer todo caminho necessário para se obter um valor JSON. Para identificação deste caminnho, torna-se encessário utilizar algo similar a uma sintaxe JavaScript para fazer referência a propriedades em texto JSON. Alguns exemplos são:
  1. ‘$’ – faz referência a todo objeto JSON no texto de entrada;
  2. ‘$.property1’ – referências property1 no objeto JSON;
  3. ‘$[5]’ – referencia 5-th elemento na matriz JSON;
  4. $. property1.property2.array1 [5].property3.array2 [15] .property4 ‘ – referências complexa Propriedade aninhada no objeto JSON.
  • O sinal de cifrão ($) representa o objeto de entrada JSON (semelhante ao iniciar / em XPath). Você pode adicionar qualquer JavaScript como referências de propriedade/matriz após o item de contexto para fazer referência a qualquer propriedade de aninhados. Importante destacar que esta função esta disponível a partir da versão SQL Server 2016 Community Technology Preview 3.2
  • JSON_Query: A função JSON_Query também é uma função texto que possui a finalidade de reconhecer e extrair um determinado valor “objeto” existente no formato JSON, sendo este um único ou um conjunto de caracteres.
  • OPENJSON: Uma das mais importantes funções, a OPENJSON irá fornecer a capacidade de analisar o texto JSON e retornar propriedades como uma tabela relacional usando a função de valor de tabela interna OPENJSON. Através da utilização da OPENJSON podemos ter explicitamente definido o esquema de resultados ou esquema padrão será usada. OPENJSON fornece uma visão de conjunto de linhas sobre um documento JSON. Porque o OPENJSON é um provedor de conjunto de linhas, que pode ser usado em instruções Transact-SQL em qual conjunto de linhas de uma tabela, visão ou até mesmo em conjunto com funções similares ao OPENROWSET.

 

 

Como indexar documentos e dados JSON

Quando a Microsoft anuncio o suporte ao JSON no SQL Server, muitos se perguntavam e ainda devem estar se perguntando. “Como será possível realizar a indexação ou algum tipo de indexação de dados no formato JSON?”

Esta pode parecer uma pergunta complicado de se responder ou até mesmo imaginar que possa existir uma resposta, mas como grande surpresa e reconhecimento da capacidade profissional do time de desenvolvimento do SQL Server, existe sim um resposta, nada muito diferente do que já estamos acostumados a utilizar no SQL Server.

A capacidade de se trabalhar com índices de diferentes formas e tipos de dados é algo que de longe não existem em nenhum outro SGBD – Sistema Gerenciador de Banco de Dados, característica singular do SQL Server, desde o reconhecimento de forma nativa de índices XML adicionados ao Microsoft SQL Server 2005 e posteriormente os fantásticos índices de cobertura presentes no Microsoft SQL Server 2008 R2, sem se esquecer do ColumnStore Index criados a partir da versão 2012.

Para que possamos fazer uso de índices para nossos dados no formato JSON, inicialmente não precisamos criar nada de diferente em relação a outras situações, basta através do comando Create Index criar um novo índice especificando qual ou quais colunas deverão fazer parte deste índice. A principal diferença é que o uso do índice no momento em que nossa query for executada esta atrelado a declaração da coluna JSON_Value, sendo esta condição para que o query optimizer possa ser notificado e posteriormente venha a reconhecer o uso ou não deste elemento de pesquisa e ordenação de dados.

Observação: Vale ressaltar que todo e qualquer índice será utilizado em uma operação de busca de dados, principalmente se o query optimizer entender a sua necessidade. No caso de um índice com base em dados JSON, a função JSON_Valeu tem que reconhecer de forma idêntica a coluna e caminho no formato JSON para que seja possível obter o dado de uma maneira mais ágil e eficiente.

Agora que você já conhece um pouco sobre as funções específicas para uso do JSON e também a forma maneira que os índices para tipos de dados JSON podem ser utilizados, vamos seguir em frente e brincar um pouco com alguns exemplos apresentados abaixo.

Exemplos

Para estes exemplos, vou utilizar o mesmo cenário apresentado na primeira parte. Vou utilizar novamente minha Virtual Machine criada no Microsoft Azure, rodando o SQL Server 2016 CTP3 (versão lançada em 28/10/2015 – http://blogs.technet.com/b/dataplatforminsider/archive/2015/10/28/sql-server-2016-everything-built-in.aspx) e AdventureWorks2016CTP3 disponível para o 2016, caso você queira montar o mesmo ambiente rodando stand-alone, faça download do SQL Server 2016 e AdventureWorks, ou saber mais sobre esta nova versão acesse:

  1. http://blogs.technet.com/b/dataplatforminsider/archive/2015/10/28/sql-server-2016-everything-built-in.aspx
  2. https://www.microsoft.com/en-us/evalcenter/evaluate-sql-server-2016
  3. https://azure.microsoft.com/en-us/marketplace/partners/microsoft/sqlserver2016ctp3evaluationwindowsserver2012r2/
  4. http://www.microsoft.com/en-us/download/details.aspx?id=49502

Vamos por a mão na massa como eu sempre digo aos meus alunos: “Quem não pratica, não aprende”. Desta forma, let’s go:

— Exemplo 1 – Utilizando a função ISJSON –

CREATE TABLE MyTable(

Id int,

jsonCol1 varchar(MAX) CHECK (ISJSON(jsonCol1)>0),

jsonCol2 varchar(4000));

ALTER TABLE MyTable

ADD CONSTRAINT jsonCol2_is_json CHECK (ISJSON(jsonCol2) > 0);

GO

 

SELECT id, json_col

FROM tab1

WHERE ISJSON(json_col) > 0

GO

 

— Exemplo 2 – Utilizando a função JSON_VALUE –

Declare @VarJSON NVarchar(400)

Set @VarJSON =

N'{

“info”:{

“type”:1,

“address”:{

“town”:”Bristol”,

“county”:”Avon”,

“country”:”England”

},

“tags”:[“Sport”, “Water polo”]

},

“type”:”Basic”

}’

 

SELECT FirstName, LastName,

JSON_VALUE(jsonInfo, ‘$.info.address[0].town’) AS Town

FROM Person.Person

WHERE JSON_VALUE(jsonInfo, ‘$.info.address[0].state’) like ‘US%’

ORDER BY JSON_VALUE(jsonInfo, ‘$.info.address[0].town’)

Go

 

— Exemplo 3 – Utilizando a função JSON_Query –

Declare @jsoninfo nvarchar(400)

Set @jsoninfo =

N'{

“info”:{

“type”:1,

“address”:{

“town”:”Bristol”,

“county”:”Avon”,

“country”:”England”

},

“tags”:[“Sport”, “Water polo”]

},

“type”:”Basic”

}’

 

SELECT FirstName, LastName,

JSON_QUERY(@jsoninfo, ‘$.info.address’) AS Address

FROM Person.Person

ORDER BY LastName

Go

Figura-1-JSON

Figura 1 – Utilizando a função JSON_Query.

— Exemplo 4 – Utilizando a função OPENJSON –

SELECT * FROM OPENJSON(‘[“Brasil”,

“United Kingdom”,

“United States”,

“Índia”,

“Singapore”,

“Marrocos”,

“Suriname”]’)

Go

Figura-2-JSON

Figura 2 – Utilizando a função OPENJSON.

— Exemplo 5 – Utilizando a função OPENJSON para transformar JSON Texto em uma relational Table –

Declare @JSalestOrderDetails NVarchar(4000)

 

Set @JSalestOrderDetails =

‘{“OrdersArray”: [

{“Number”:1, “Date”: “8/10/2012”, “Customer”: “Adventure works”, “Quantity”: 1200},

{“Number”:4, “Date”: “5/11/2012”, “Customer”: “Adventure works”, “Quantity”: 100},

{“Number”:6, “Date”: “1/3/2012”, “Customer”: “Adventure works”, “Quantity”: 250},

{“Number”:8, “Date”: “12/7/2012”, “Customer”: “Adventure works”, “Quantity”: 2200}

]}’

 

SELECT Number, Customer, Date, Quantity_

FROM OPENJSON (@JSalestOrderDetails, ‘$.OrdersArray’)

WITH (

Number varchar(200),

Date datetime,

Customer varchar(200),

Quantity int

) AS OrdersArray

Go

Figura-3-JSON

Figura 3 – Transformando um JSON Text em tabela relacional.

— Exemplo 6 – Trabalhando com índices e dados JSON —

CREATE TABLE SalesOrderRecord

( Id int PRIMARY KEY IDENTITY,

OrderNumber NVARCHAR(25) NOT NULL,

OrderDate DATETIME NOT NULL,

JOrderDetails NVARCHAR(4000),

Quantity AS CAST(JSON_VALUE(JOrderDetails, ‘$.Order.Qty’) AS int),

Price AS JSON_VALUE(JOrderDetails, ‘$.Order.Price’))

GO

CREATE INDEX idxJson ON SalesOrderRecord(Quantity) INCLUDE (Price);

Go

 

Conclusão

O Microsoft SQL Server 2016 esta chegando e com ele uma série de novas funcionalidades, melhorias e inovações estão sendo apresentadas, entre estes itens o JSON é um dos mais aguardados.

A tecnologia JSON criada inicialmente como uma forma de se consumir dados de maneira mais simples em comparação ao formato XML, torna-se uma referência mundial e isso fez com que a Microsoft e seu tipo de engenheiros do SQL Server entende-se a necessidade de adicionar este recurso ou melhor dizendo funcionalidade ao produto.

Nesta parte final, você pode conhecer mais sobre o JSON, como é possível indexar um documento ou dados em formato JSON, o uso de funções próprias para se trabalhar com este tecnologia, bem como, o SQL Server consegui tratar, interpretar e apresentar estes dados.

Espero que você tenha gostado deste artigo, que as informações compartilhadas aqui possam lhe ajudar, mostrando como o Microsoft SQL Server esta a cada dia se tornando um ambiente completo de Gerenciamento de Banco de Dados totalmente compatível com diversas tecnologias e linguagens de programação.

 

Agradecimentos,

Agradeço a todos que estiveram visitando meu blog neste ano de 2015, com certeza a presença de vocês é de total importância, mais uma vez conseguir obter um número expressivo de visitantes e leitores, sem falar no número de seguidores que constantemente cresce. Espero em 2016 poder contar ainda mais com a sua presença.

Desejo um Feliz Ano Novo, repleto de Paz, Saúde, Alegria, Conquistas e Realizações.

Nos encontramos em breve.

Até a próxima.

Short Scripts – Agosto 2015


Boa tarde, Comunidade!!!!

Tudo em paz? Mas que loucura este tempo aqui em São Roque e Sorocaba, hoje ás 6:30hrs da manhã estava 8º graus, agora ás 13hrs sensação térmica de 20º graus e subindo……

Nos últimos meses acabei deixando de publicar alguns posts relacionadas a minha sessão Short Scripts devido a correria da vida profissional e acadêmica, mas hoje vou pagar este dívida, compartilhando com vocês alguns dos meus novos short scripts.

Muitos tem me perguntado o porque acabou guardando tantos scripts ou códigos de exemplo, a resposta é bem simples e direta, sempre existirá alguém ou algo no mundo que poderá necessitar deste recurso e isso é que me mantem nesta jornada em cultivar minha biblioteca de scripts a cada dia mais atualização e completa(tarefa muito, mas muito complicada de se realizar).

Os Short Scripts apresentados hoje, estão relacionandos com os seguintes assuntos:

  • Block Process;
  • CTE;
  • Claúsula Output;
  • Comando Select;
  • Comando SET;
  • Concatenação de Valores;
  • Extended Events;
  • Índices;
  • Junção de Tabelas
  • Fatorial;
  • Funções; e
  • Tipos de Dados.

É isso galera, a seguir você vai poder encontrar os blocos de código que representam os Short Scripts, fique a vontade para copiar, compartilhar, sugerir melhorias e fazer suas críticas também.

 

— Short Script 1 –  Uitlizando claúsula Output em Delete com Inner Join + Select —

DECLARE @t TABLE

(nDex INT IDENTITY(1,1),

valu VARCHAR(9),

keey UNIQUEIDENTIFIER)

INSERT @t

VALUES (‘a’,NEWID()) , (‘b’,NEWID()),

(‘c’,NEWID()) , (‘d’,NEWID()),

(‘e’,NEWID()) , (‘f’,NEWID()),

(‘g’,NEWID()) , (‘h’,NEWID()),

(‘i’,NEWID()) , (‘j’,NEWID()),

(‘k’,NEWID())

DELETE t

OUTPUT DELETED.*

FROM @t AS t INNER JOIN (SELECT TOP 9 nDex FROM @t ORDER BY NEWID()) AS b

ON b.ndex = t.nDex

GO

 

 

— Short Script 2 – Uitilizando – CTE para separar palavras —

DECLARE @s VARCHAR(8000), @d VARCHAR(10)

SET @s = ‘separar por espaço em branco’

SET @d = ‘ ‘

;WITH split(i,j) AS

(

SELECT i = 1, j = CHARINDEX(@d, @s + @d)

UNION ALL

SELECT i = j + 1, j = CHARINDEX(@d, @s + @d, j + 1) FROM split

WHERE CHARINDEX(@d, @s + @d, j + 1) <> 0

)

SELECT SUBSTRING(@s,i,ji)

FROM split

 

— Short Script 3 – Simulando – Cenários de utilização de índices —

USE TempDB;

— Criando a Tabela Funcionário —

CREATE TABLE Funcionario

(ID int primary key,

NomeFunc varchar(200),

DataNasc date,

DataADM date);

Go

— Consulta 1 – Fazendo uso do Operador Clustered Index Scan —

SELECT * from Funcionario

Where DataADM between Convert(date, ‘1/1/2012’, 103) and Convert(date, ’31/1/2012′, 103)

Go

— Criando um novo índice chamado Ind_NC_Funcionario_DataADM —

CREATE Nonclustered Index Ind_NC_Funcionario_DataADM On Funcionario (DataADM);

Go

— Consulta 2 – Fazendo uso do Operador Clustered Index Scan —

SELECT * from Funcionario

Where DataADM between Convert(date, ‘1/1/2012’, 103) and Convert(date, ’31/1/2012′, 103)

Go

— Consulta 3 – Forçando o uso do índice IND_NC_Funcionario_DataADM, gerando Index Seek, Key Lookup e Nested Loops —

SELECT * from Funcionario with (index=Ind_NC_Funcionario_DataADM)

Where DataADM between Convert(date, ‘1/1/2012’, 103) and Convert(date, ’31/1/2012′, 103)

Go

— Consulta 4 – Utilizando realmente o índice IND_NC_Funcionario_DataADM —

SELECT ID, DataADM

From Funcionario

Where DataADM between Convert(date, ‘1/1/2012’, 103) and Convert(date, ’31/1/2012′, 103)

Go

 

— Short Script 4 – Função – Concatenar valores em ordem decrescente —

CREATE FUNCTION dbo.ConcatenaValores (@C1 int, @C2 int, @C3 int, @C4 int, @C5 int)

returns int as

begin

declare @Concatenado varchar(5);

set @Concatenado= space(0);

SELECT @Concatenado+= Cast(N as char(1))

from (values (@C1), (@C2), (@C3), (@C4), (@C5)) as Numeros(N)

order by N desc;

return Cast(@Concatenado as int);

end;

go

Select Valor= dbo.ConcatenaValores(1, 2, 3, 4, 5);

 

— Short Script 5 – Criando tipo de dados NotNull mas Null sobrepondo Not Null —

CREATE TYPE NotNullType FROM VARCHAR(10) NOT NULL;

GO

— table create

CREATE TABLE Test(TestId INT, NullTest NotNullType NULL);

GO

— insert

INSERT INTO Test(TestId) VALUES(1);

SELECT NullTest FROM Test;

 

— Short Script 6 – Comparando comportamento entre os comandos SET e Select —

DECLARE @a INT= 0;

DECLARE @b INT= 0;

 

CREATE TABLE #tmpPrice ( Value INT );

SET @a = ( SELECT Value FROM #tmpPrice);

SELECT @b = Value FROM #tmpPrice;

SELECT @a AS, @b AS b

 

— Short Script 7 – Função para Calcular Fatorial com CTE encapsulada —

CREATE FUNCTION fatorial

(

@n INT

)

RETURNS INT

AS

BEGIN

DECLARE @val INT;

WITH fat(f, n) AS

(

SELECT CAST (1 as bigint) as f, 0 as n

UNION ALL

SELECT CAST (1 as bigint) as f, 1 as n

UNION ALL

SELECT f * (n + 1), n +1

FROM fat

WHERE n < 20 AND n <> 0

)

SELECT @val = f

FROM fat

WHERE n = @n

RETURN @val

END

GO

— Testando a função

SELECT dbo.fatorial(3);

SELECT dbo.fatorial(4);

SELECT dbo.fatorial(7);

 

— Short Script 8 –  CTE – Calculando fatorial —

WITH fat(f, n) AS

(

SELECT CAST (1 as bigint) as f, 0 as n — fat de 0 é 1

UNION ALL

SELECT CAST (1 as bigint) as f, 1 as n — fat de 1 é 1

UNION ALL

SELECT f * (n + 1), n +1

FROM fat

WHERE n < 20 AND n <> 0

— 20 é o limite neste caso, pois o fatorial de 21

— não cabe em um tipo bigint. O <> 0 é para cortar a recursão

— do primeiro âncora, senão repetiria tudo, faça o teste.

)

SELECT f

FROM fat

WHERE n = 12

 

— Short Script 9 – Capturar Blocked Process com Extended Events —

CREATE EVENT SESSION [Blocked] ON SERVER

ADD EVENT sqlserver.blocked_process_report

ADD TARGET package0.event_file

(SET filename=N’C:\xel\blocked.xel’)

GO

ALTER EVENT SESSION [Blocked]

ON SERVER

STATE = start;

GO

 

–Agora precisamos ler os arquivos .XEL gerados pela sessão e extrair os dados do XML para identificarmos as causas dos blocked process:

select theNodes.event_data.value(‘(//blocked-process/process)[1]/@spid’,‘int’) as blocking_process,

theNodes.event_data.value(‘(//blocked-process/process/inputbuf)[1]’,‘varchar(max)’) as blocking_text,

theNodes.event_data.value(‘(//blocked-process/process)[1]/@clientapp’,‘varchar(100)’) as blocking_app,

theNodes.event_data.value(‘(//blocked-process/process)[1]/@loginname’,‘varchar(50)’) as blocking_login,

theNodes.event_data.value(‘(//blocked-process/process)[1]/@isolationlevel’,‘varchar(50)’) as blocking_isolation,

theNodes.event_data.value(‘(//blocked-process/process)[1]/@hostname’,‘varchar(50)’) as blocking_host,

theNodes.event_data.value(‘(//blocking-process/process)[1]/@spid’,‘int’) as blocked_process,

theNodes.event_data.value(‘(//blocking-process/process/inputbuf)[1]’,‘varchar(max)’) as blocked_text,

theNodes.event_data.value(‘(//blocking-process/process)[1]/@clientapp’,‘varchar(100)’) as blocked_app,

theNodes.event_data.value(‘(//blocking-process/process)[1]/@loginname’,‘varchar(50)’) as blocked_login,

theNodes.event_data.value(‘(//blocked-process/process)[1]/@isolationlevel’,‘varchar(50)’) as blocked_isolation,

theNodes.event_data.value(‘(//blocking-process/process)[1]/@hostname’,‘varchar(50)’) as blocked_host

from

(select convert(xml,event_data) event_data

from

sys.fn_xe_file_target_read_file(‘c:\xel\blocked*.xel’, NULL, NULL, NULL)) theData

cross apply theData.event_data.nodes(‘//event’) theNodes(event_data)

 

Chegamos ao fim de mais um Short Scripts, espero que você tenha gostado destes códigos!!!

Nos encontramos em breve.

Até a próxima…..