quarta-feira, 14 de maio de 2008

Novos tipos de dados do SQL 2008: HIERARCHYID (Parte 1)

Este artigo foi escrito utilizando o CTP de Novembro do SQL Server 2008.

Minha esposa acabou de entrar no Teatro com meus dois filhos (Luaninha e Erick) e fiquei no restaurante para trabalhar em um projeto que está começando a atrasar.... é um projeto de BI e a fase atual de documentação do ETL é a mais chata!!! Após a primeira garrafa de Bohemia (muiiiito gelada!), resolvi escrever um post, só para relaxar.

Vou escrever sobre o novo tipo de dados hierárquico em dois posts, no primeiro veremos como criar e manipular hierarquias no SQL Server 2005, no próximo veremos as novidades no SQL Server 2008, OK?

Hierarquia no SQL Server 2005
Vamos utilizar como exemplo a hierarquia da figura abaixo:




A abordagem tradicional para lidar com hierarquia utiliza auto-relacionamento, veja o script abaixo que cria no SQL Server 2005 a hierarquia da figura acima:

USE tempdb
go

CREATE TABLE Funcionario(
FuncionarioID int not null primary key,
Nome varchar(40) not null,
Cargo varchar(20) not null,
ChefeID int null)
go

INSERT Funcionario VALUES (1,'Jose','Presidente',null)
INSERT Funcionario VALUES (2,'Maria','Diretor',1)
INSERT Funcionario VALUES (3,'Pedro','Diretor',1)
INSERT Funcionario VALUES (4,'Ana','Gerente',2)
INSERT Funcionario VALUES (5,'Lucia','Gerente',2)
INSERT Funcionario VALUES (6,'Ronaldo','Gerente',3)
INSERT Funcionario VALUES (7,'Marcio','Coordenador',5)
go




Algumas operações comuns em hierarquia podem ser bem complexas no SQL Server 2005, como retornar todos os subordinados de um funcionário. Na consulta abaixo vamos retornar todos os subordinados da Diretora Maria, utilizando CTE com recursividade:

WITH Organograma (FuncionarioID, Nome, Cargo, ChefeID)
AS (
-- Cria a ancora para estabelecer ponto inicial
SELECT FuncionarioID, Nome, Cargo, ChefeID FROM Funcionario
WHERE Nome = 'Maria'
UNION ALL
-- Cria recursividade
SELECT f.FuncionarioID, f.Nome, f.Cargo, f.ChefeID
FROM Funcionario f JOIN Organograma o
ON f.ChefeID = o.FuncionarioID)

SELECT * FROM Organograma
go




Para incluir um novo funcionário Gerente no lugar de Ana, deslocando-a para Coordenadora, será necessário fazer vários UPDATEs nos seus subordinados.

No próximo post veremos como ficou mais fácil manipular hierarquias no SQL Server 2008, Até lá.
Landry.

quarta-feira, 7 de maio de 2008

Novos tipos de dados do SQL 2008: DATETIMEOFFSET

Este artigo foi escrito utilizando o CTP de Novembro do SQL Server 2008.

Nos dois últimos posts (http://sqlserver-brasil.blogspot.com/2008/04/novos-tipos-de-dados-do-sql-2008-date-e.html e http://sqlserver-brasil.blogspot.com/2008/04/novos-tipos-de-dados-do-sql-2008.html), escrevi sobre três tipos de dados novos para Data e Hora (DATE, TIME e DATETIME2). Neste post irei completar a série destinada aos novos tipos de dado Date e Time, escrevendo sobre suporte a Time Zone com o novo DATETIMEOFFSET.

DATETIMEOFFSET
Este tipo de dados é similar ao DATETIME2 onde é informada a precisão da hora, com acréscimo do Time Zone no intervalo de -14:00 a +14:00. Veja o exemplo abaixo:

DECLARE @dt DATETIMEOFFSET(0)
SET @dt = '20080415 22:00:00 -3:00' -- Brasilia

DECLARE @dt1 DATETIMEOFFSET(0)
SET @dt1 = '20080415 22:00:00 +9:00' -- Tokio

SELECT DATEDIFF(hh,@dt,@Dt1) 'Diferença Fuso Brasilia e Tokio'

-- Resultado abaixo:

Diferença Fuso Brasilia e Tokio
-------------------------------------------
-12


Vamos comparar agora todos os novos tipos de dados Data e Hora com os antigos DATETIME e SAMLLDATETIME:

SELECT CAST('20080120 20:30:05.1234567 +5:0' as DATE)
-- Resultado DATE: 2008-01-20

SELECT CAST('20080120 20:30:05.1234567 +5:0' as TIME(7))
-- Resultado TIME: 20:30:05.1234567

SELECT CAST('20080120 20:30:05.123' as SMALLDATETIME)
-- Resultado SMALLDATETIME: 2008-01-20 20:30:00.000

SELECT CAST('20080120 20:30:05.123' as DATETIME)
-- Resultado DATETIME: 2008-01-20 20:30:05.123

SELECT CAST('20080120 20:30:05.1234567 +5:0' as DATETIME2(7))
-- Resultado DATETIME2: 2008-01-20 20:30:05.1234567

SELECT CAST('20080120 20:30:05.1234567 +5:0' as DATETIMEOFFSET(7))
-- Resultado DATETIMEOFFSET: 2008-01-20 20:30:05.1234567 +05:00

No próximo post vou mostrar o tipo de dado hierarquico, Até lá.
Landry.