Lucas's profileLucas Souza [MCP | MCTS ...PhotosBlogListsMore Tools Help

Blog


    September 12

    O que são Views no SQL Server¿

    Simplismente pode ser descrito como uma ou mais instrução SELECT contendo schema, colunas, atributos, etc.  As views são comumente conhecidas como tabelas virtuais as quais tem por objetivo capturar colunas de tabelas existentes no banco de dados, desta forma podemos definir o nome específico da view e armazenar-la no banco de dados. A maior vantagem das Views é criar-las contendo uma ou mais instrução SELECT, a sintaxe da criação da view mostra-se abaixo:

    CREATE VIEW [ schema_name . ] view_name [ (column [ ,...n ] ) ]

    [ WITH <view_attribute> [ ,...n ] ]

    AS select_statement

    [ WITH CHECK OPTION ] [ ; ]

     

    <view_attribute> ::=

    {

        [ ENCRYPTION ]

        [ SCHEMABINDING ]

        [ VIEW_METADATA ]     }

     

    Apartir do momento que sabemos que as views armazenam instruções SELECT definida  pelo usuário, além disso vale lembrar que as instruções SELECT pode ser referenciada por tabelas, views ou até mesmo funções.

     

    BENEFÍCIOS

    o    Nos garante um mecanismo de segurança que restringe aos usuários ter permissões nos dados em uma ou mais tabelas;

    o    Garante os desenvolvedores visualizarem apenas os dados armazenados em tabelas lógica;

    o    Mineração de dados através de cargas de trabalho;

    o    Data warehouses;

    o    Data marts;

    o    Armazenar e originar processamento analítico online (OLAP)

    o    Decisão para suportar cargas de trabalho

     

    LIMITAÇÕES

    o    Usar a cláusula OPTION;

    o    Usar a palavra-chave INTO;

    o    Referenciar tabelas temporárias, variáveis ou outros tipos;

    o    Contêr a cláusula ORDER BY ao menos que específique o operador TOP;

    o    Contêr a cláusula COMPUTE ou COMPUTE BY.

    OBS: As views podem contêr múltiplas instruções SELECT juntamente utilizadas com os operadores UNION ALL ou UNION;
    A view pode ser criada apenas no banco de dados atual e além disso não pode exercer o valor de 1024 colunas

    Exemplo¹:

    -- Esta view tem por objetivo a exibição de dois campos para cada tabela distinta, sendo elas: Product, Address, Customer

    CREATE VIEW dbo.ViewTeste

    AS

    SELECT ProductID, Name FROM AdventureWorks.Production.Product

    UNION ALL

    SELECT AddressID, City FROM AdventureWorks.Person.Address

    UNION ALL

    SELECT CustomerID, CustomerType FROM AdventureWorks.Sales.Customer

     

    Exemplo²:

     

    -- Esta view tem nos mostra a soma do Total de impostos da tabela SalesOrderHeader, sendo assim nos trazendo apenas os resultados em que a data esteja acima do ano 1992, mês 11, dia 25.

    CREATE VIEW dbo.TotalVendas

    AS

    SELECT TOP 100 SalesPersonID, SUM(TotalDue) AS TotalSales

    FROM Sales.SalesOrderHeader

    WHERE OrderDate > CONVERT(DATETIME,'19921125',101)

    GROUP BY SalesPersonID;

    GO

     

    Se por acaso for necessário utilizar operações de indexes nas views é necessário seguirmos alguns passos, por exemplo:

     

    o    Verifique a configuração da opção ANSI_NULLS se está corretamente assinalada para todas a tabelas existentes a qual irá ser referenciada dentro da view;

    o    Verifique a configuração ANSI_NULLS se está corretamente assinadada para a sessão atual que mostra-se dentro da tabela;

    o    Verifique as propriedades ANSI_NULLS e QUOTED_IDENTIFIER se está corretamente assinaladas as sessões atuais mostradas na tabela;

    o    Verifique se a definição da view é deterministica, para mais informações, veja: Deterministic and Nondeterministic ;

    o    Crie a view usando a opção WITH SCHEMABINDING;

    o    Verifique suas sessões com a opção SET e vejam como estar corretamente mostrada na tabela;

    o    Crie finalmente o index clustered unique dentro na view.

     

    []´s

     

    Lucas Souza

     

     

    June 13

    Utilizando a cláusula TOP no SQL Server

    Boa Noite Pessoal,

    Tenho percebido que recentemente tenho recebido alguns emails de colegas pelos quais trabalham com C# e ASP.NET, infelizmente alguns deles estão se dando com simples problemas nos quais podem ser resolvidos utilizando funções simples, todavia sabemos que o SQL Server possuí inúmeras funções das quais podem ser bastantes úteis em nosso dia a dia.

    Sabemos que a cláusula TOP é frequentemente mais utilizada juntamente com a instrução SELECT, todavia uma boa dica é: definir uma variável e atribuir um valor(int) á ela ou até mesmo uma porcentagem(%) pelo qual seria o valor que estariamos atribuindo a cláusula(TOP) na instrução SELECT.

    Syntax :

    [
         TOP (expression) [PERCENT]
         [ WITH TIES ]
    ]

    -- TOP - Frequentemente mais utilizado (int) (Subquery)

    SELECT TOP

    (

        SELECT COUNT(ListPrice) / 5

        FROM Production.Product

     )

        ProductNumber,

        StandardCost,

        ProductID,

        ListPrice

    FROM Production.Product

    ORDER BY

          ProductNumber,

        StandardCost,

        ProductID,

          ListPrice

     

     
     

    -- TOP - Frequentemente mais utilizado (Porcentagem)(Subquery)

    SELECT TOP

    (

        SELECT COUNT(ListPrice) / 7

        FROM Production.Product

     ) PERCENT

        Name,

        ModifiedDate,

        Color,

        ListPrice

    FROM Production.Product

    ORDER BY

          Name,

          ModifiedDate,

          Color,

          ListPrice

     

    -- TOP - declaração variável (código estruturado - porcentagem)

    DECLARE @Variavel1 FLOAT = 2;

    SELECT TOP(@Variavel1) PERCENT ListPrice

        Name,

        ModifiedDate,

        Color

    FROM Production.Product

    ORDER BY

          ModifiedDate,

          Color

    -- TOP - declaração variável (código estruturado - inteiro)

    DECLARE @Variavel2 INT = 7

    SELECT TOP (@Variavel2) ListPrice,

        ProductNumber,

        StandardCost,

        ProductID,

        ModifiedDate

    FROM Production.Product

    ORDER BY

          ProductNumber,

        StandardCost,

        ProductID,

          ModifiedDate

    A microsoft recomenda que sempre ao utilizar a cláusula TOP é necessário utilizarmos os parêntesis, todavia por questão de compatibilidade de scripts do SQL Server 200 e 2005, sendo assim os parêntesis não são obrigatoriamente necessário ao especificarmos a cláusula TOP.
     * A cláusula TOP não pode ser usada juntamente com instruções UPDATE e DELETE em views(visões particionadas.

    []’s

    Lucas Souza

    June 10

    Acessando metadados através de Catalog Views e Dynamic Management Views no SQL Server

    O SQL Server vem sempre nos permitindo e garatindo termos um acesso mais robusto e mais vantajoso, sendo assim sempre nos oferecendo inúmeros metadados para termos um desenvolvimento mais flexível e mais fácil, todavia estes metadados podem ser descritos através de: sistemas de tabelas, databases, views entre outros.

    Dynamic Management views and functions geralmente é utilizado para retornar o estado de como o servidor está se comportando ao receber consultas pelas quais estão sendo executados por Users,DBA´s entre outros, sendo assim podemos utilizar-las(DMV´s) para buscarmos por: instância do servidor, diagnosticar problemas e a questão de tuning.

    Muitos catálogos podem serem acessados através da cláusula ‘sys’, por exemplo se quisermos buscar por uma informação (x) de uma tabela podemos utilizar o comando: SYS.TABLES do qual nos traz ‘nome da tabela (name)’, ‘id objeto(object id)’ o qual é mais utilizado para quando não temos o nome exato de uma tabela, ‘id schema (schema_id) bastante útil também para buscarmos uma referência completa nos trazendo assim tanto o schema como a a tabela se fizermos por exemplo inner join.

    Se por acaso em algum momento precisarmos de uma consulta que nos mostre algumas informações básicas como por exemplo: nome do schema + nome da tabela + tipo de tabela + nome de coluna, podemos utilizar uma consulta similar á essa, sendo assim você pode remover ou adicionar mais colunas conforme a sua necessidade.

    SELECT

    s.name AS schema_name,

    t.name AS table_name,

    t.type_desc AS table_type,

    c.name AS column_name,

    c.column_id,

    ty.name AS data_type_name,

    c.max_length,

    c.precision,

    c.scale,

    c.is_nullable

    FROM sys.schemas s

    INNER JOIN sys.tables t

    ON s.schema_id = t.schema_id

    INNER JOIN sys.columns c

    ON t.object_id = c.object_id

    INNER JOIN sys.types ty

    ON c.system_type_id = ty.system_type_id

    AND c.user_type_id = ty.user_type_id

    WHERE s.name = 'Person'

    AND t.name = 'Address';

     

     

    Certa vez pode ser útil termos um resultado conforme o que mostra na imagem acima, neste caso podemos identificar certas áreas importantes, mapea-las e aplicar o que for necessário e no momento correto.

     

    O SQL Server provê aproximadamente 80 DMVs e DMFs  á qual tem seu objetivo de nos informar metadados relacionado ao acesso interno no servidor, ultimamente os desenvolvedores ao utilizar as DMV´s e DMF´s podem ter grandes benefícios, um deles seria ‘um caminho mais curto’ neste caso ao invés de utilizarmos uma consulta complexa como era em versões anteriores podemos agora simplificar e termos um código mais’ limpo’ .

     

    O SQL Server possuí um escopo de DMV´s e DMF´s dentro do banco de dados no servidor, sendo assim iniciando-se pelo prefixo dm_*.

    Sys.dm_cdc_* - Contêm informações sobre Change Data Capture (CDC) transações e log de sessões, Essa é uma nova feature do SQL Server 2008 o qual tem seu objetivo de capturar informações relacionadas ao código T-SQL;

    Sys.dm_exec_* - Tem seu objetivo retornar informações relacionado ao código executado pelo usuário;

    Sys.dm_fts_* - Tem seu objetivo retorna informações sobre a funcionalidade do Integrated Full-Text Search (iFTS), Full Text Search é um componente do SQL Server o qual possuí um grande potencial ao buscar por palavras, textos .doc, .pdf entre outros;

    Sys.dm_os_* - Nos mostra detalhes de baixo nível de bloqueios, memória usada e agendada;

    Sys.dm_trans_* - Provê informações sobre transações que estão sendo executada em tempo real e bloqueios;

    Sys_dm_io_* -  Permite que você monitore a rede e o DISCO I/O;

    Sysm_dm_db_* - Retorna informações sobre banco de dados e o level dos objetos no banco.

     

     

    Neste caso por exemplo podemos elaborar uma consulta que nos permita vermos o valor de cpu utilizada, memória utilizada, total de leituras, total de escritas entre outros.

    SELECT

    login_name,

    SUM(cpu_time) AS tot_cpu_time,

    SUM(memory_usage) AS tot_memory_usage,

    AVG(total_elapsed_time) AS avg_elapsed_time,

    SUM(reads) AS tot_reads,

    SUM(writes) AS tot_writes,

    SUM(logical_reads) AS tot_logical_reads,

    COUNT(session_id) as tot_sessions

    FROM sys.dm_exec_sessions

    WHERE session_id > 50

    GROUP BY login_name;

     

     

    Neste caso ao termos em mente quanto um usuário ou administrador está consumindo nas consultas diárias em nosso servidor, podemos adequirir certas permisões para evitarmos que nosso servidor sofra um gargalho inesperado, ao utilizarmos as DMV´s e DMF´s em nossa aplicação dia á dia podemos agora obter um código mais limpo e bem mais fácil de entendermos.

    Observação: Os catalog views não contém informações á respeito de manutenção de planos, backup, replicação ou SQL Server Agent.

     

    []’s
    Lucas Souza

    June 07

    Utilizando Triggers no SQL Server (Overview) Parte 04 (Final)

    Logon Triggers:

     

    O SQL Server nos oferece também outro tipo de gatilho, no entanto ele não é muito conhecido, porém bastante útil o qual está dísponivel em versão posteriores do SQL Server 2005 SP2. Esse gatilho é responsável por disparar operações de LOGON depois da autênticação for efetuada.

     

    IF OBJECT_ID ('dbo.DenyLogonSchedule ') IS NOT NULL

       DROP TABLE dbo.DenyLogonSchedule;

    GO

     

    CREATE TABLE dbo.DenyLogonSchedule

    (

    UserId sysname NOT NULL,

    DayOfWeek int NOT NULL,

    TimeStart time NOT NULL,

    TimeEnd time NOT NULL,

    PRIMARY KEY (UserId, DayOfWeek, TimeStart, TimeEnd)

    );

     

    INSERT INTO dbo.DenyLogonSchedule

    (

    UserId,

    DayOfWeek,

    TimeStart,

    TimeEnd

    )

    VALUES

    (

    'PublicUser',

    7,

    '21:00:00',

    '23:00:00'

    );

    GO

     

    IF OBJECT_ID ('DenyLogons') IS NOT NULL

       DROP TRIGGER DenyLogons;

    GO

     

    CREATE TRIGGER DenyLogons

    ON ALL SERVER

    WITH EXECUTE AS 'sa'

    FOR LOGON

    AS

    BEGIN

    IF EXISTS

    (

    SELECT 1

    FROM AdventureWorks.dbo.DenyLogonSchedule

    WHERE UserId = ORIGINAL_LOGIN()

    AND DayOfWeek = DATEPART(WeekDay, GETDATE())

    AND CAST(GETDATE() AS TIME) BETWEEN TimeStart AND TimeEnd

    )

    BEGIN

    ROLLBACK TRANSACTION;

    END;

    END;

    GO

     

    Percebam que ter um gatilho com esse objetivo pode ser muito útil, se precisamos por exemplo definir um horário padrão para um certo usuário que possa utilizar o banco de dados para executar uma tarefa x, podemos no entanto adotar esse tipo de gatilho e alterar o que for necessário.
    Lembrando que essa funcionalidade de gatilhos LOGON foram introduzidos no SQL Server 2005 SP2, sendo assim o objetivo dessa funcionalidade é: capturar eventos de LOGIN, se quisermos algo relacionado á outra funcionalidade podemos escolher qual dos 2 acimas DDL ou DML dependendo da sua necessidade em seu negócio.

     

    []’s

    Lucas Souza

     

    June 06

    Utilizando Triggers no SQL Server (Overview) Parte 03

     

    DDL Triggers:

    Desde a versão do SQL Server 2005 os programadores T-SQL tem á habilidade de criar gatilhos DDL que por sua vez tem o objetivo de disparar quando os eventos DDL’s dos triggers ocorrem no banco de dados ou no servidor.

    Os triggers DDL são úteis para evitar que ocorra mudanças inesperadas no banco de dados, mudanças essas que se referem a auditoria ou algo relacionado á isto.
    Uma vez falado dos triggers DDL, podemos também utilizar o evento EVENTDATA o qual é responsável por retornar informações de tempo, conexão, nome do objeto, tipo do evento entre outros sendo assim disparados pelo triggers.

     

    IF OBJECT_ID ('dbo.DDlActionLog') IS NOT NULL

       DROP TABLE dbo.DDlActionLog;

    GO

     

    CREATE TABLE dbo.DdlActionLog

    (

    EntryNum int IDENTITY(1, 1) NOT NULL PRIMARY KEY,

    EventType nvarchar(200) NOT NULL,

    PostTime datetime NOT NULL,

    Spid int NOT NULL,

    LoginName sysname NOT NULL,

    UserName sysname NOT NULL,

    ServerName sysname NOT NULL,

    SchemaName sysname NOT NULL,

    DatabaseName sysname NOT NULL,

    ObjectName sysname NOT NULL,

    ObjectType sysname NOT NULL,

    CommandText nvarchar(max) NOT NULL

    );

    GO

     

    IF OBJECT_ID ('AuditCreateTable ') IS NOT NULL

       DROP TRIGGER AuditCreateTable;
    GO

     

    CREATE TRIGGER AuditCreateTable

    ON DATABASE

    FOR CREATE_TABLE

    AS

    BEGIN

     

    DECLARE @event_data xml;

    SET @event_data = EVENTDATA();

     

    INSERT INTO dbo.DdlActionLog

    (

    EventType,

    PostTime,

    Spid,

    LoginName,

    UserName,

    ServerName,

    SchemaName,

    DatabaseName,

    ObjectName,

    ObjectType,

    CommandText

    )

    SELECT

    EventNode.value(N'EventType[1]', N'nvarchar(200)'),

    EventNode.value(N'PostTime[1]', N'datetime'),

    EventNode.value(N'SPID[1]', N'int'),

    EventNode.value(N'LoginName[1]', N'sysname'),

    EventNode.value(N'UserName[1]', N'sysname'),

    EventNode.value(N'ServerName[1]', N'sysname'),

    EventNode.value(N'SchemaName[1]', N'sysname'),

    EventNode.value(N'DatabaseName[1]', N'sysname'),

    EventNode.value(N'ObjectName[1]', N'sysname'),

    EventNode.value(N'ObjectType[1]', N'sysname'),

    EventNode.value(N'(TSQLCommand/CommandText)[1]', 'nvarchar(max)')

    FROM @event_data.nodes('/EVENT_INSTANCE') EventTable(EventNode);

    END;

    GO

     

    Após termos criado a tabela para coletar as operações iremos nesse momento criar uma tabela de exemplo:

     

    CREATE TABLE dbo.TableTeste (i int);

    GO

     

    -- Percebam que vai nos trazer a tabela conforme criamos acima

    SELECT * FROM DdlActionLog

     

    []'s
    Lucas Souza
    http//www.souzalucas.spaces.live.com
    June 05

    Utilizando Triggers no SQL Server (Overview) Parte 02

    Continuação...

    DML Triggers:
    Como citei nos exemplos anteriores os triggers(gatilhos) DML são responsáveis por disparar operações de insert,update,delete podendo assim serem aplicados tanto em uma tabela como em uma view.
    os gatilhos DML geralmente são mais utilizados em cenários aonde envolve: validação de dados antes de serem armazenados, alterações de auditorias e regras de negócios.

    USE AdventureWorks;

    GO

     

    IF OBJECT_ID ('dbo.Table1') IS NOT NULL

       DROP TABLE dbo.Table1;

    GO

     

    CREATE TABLE dbo.Table1

    (

          ID   INT,

          NOME NVARCHAR(50)

    )

    GO

     

    IF OBJECT_ID ('Trigger1') IS NOT NULL

       DROP TRIGGER Trigger1;
    GO

     

    CREATE TRIGGER Trigger1

    ON dbo.Table1

    AFTER INSERT, UPDATE

     

    AS   

         SET NOCOUNT ON;

        

    ROLLBACK

    RAISERROR ('ERROR: Você não tem permissão para alterar ou deletar algum registro na tabela corrente', 16, 10)

    GO

    -- Visualizar o trigger criado

    SELECT * FROM sys.triggers

    WHERE name = 'Trigger1'

     

    -- Tentar Inserir um valor na tabela

    INSERT INTO dbo.Table1

    VALUES (1,'LUCAS')

      

    Percebam que esse gatilho tem o objetivo se forçar a integridade dos dados, no entanto se alguem por acaso tentar inserir ou atualizar a tabela sem a permissão desejada irá se aparecer com o erro personalizado o qual foi definido na cláusula RAISERROR.

     

    Tipos de erros e níveis de severidade

    Erros com severidade de 0 a 10: indicam os erros de severidade baixa (apenas mensagens informativas).

    ·         Erros com severidade de 11 a 16: indicam os erros de severidade média;

    ·         Erros com severidade 17: indicam as falta de recursos no sistema;

    ·         Erros com severidade 18: indicam á ocorrência de erros internos de software;

    ·         Erros com severidade 19: indicam que algum limite interno não configurável foi excedido.   

     

    ·          Erros com severidade de 20 a 25: indicam erros de maior gravidade e normalmente requerem á    intervenção do DBA.

     

    June 04

    Utilizando Triggers no SQL Server (Overview) Parte 01

    Boa Tarde Pessoal,

    Tenho percebido que ultimamente a Microsoft tem investido bastante no SQL Server, sendo assim alguns usuários que trabalham com essa tecnologia geralmente tem percebido que obtivemos grandes melhorias sendo elas diferenciadas por vastas categorias, os gatilhos no SQL Server não é uma novidade, todavia é um recurso fantástico o qual nos permite termos uma regra de negócio em nosso banco de dados mais confiável e inteligente.

    O SQL Server 2008 implementou três tipos de gatilhos conhecidos como por exemplo:

    ·          Data Manipulation Language (DML)  o qual é responsavel para disparar operações insert,update,delete em tabelas;

    ·         Data Definition Language (DDL) o qual é responsavel por disparar operações CREATE,ALTER e DROP;

    ·         Logon triggers o qual é responsavel por disparar operações de eventos de LOGON.

    Sintaxe de um Trigger é o seguinte:

    CREATE TRIGGER trigger_name

    ON { table | view }

    [ WITH ENCRYPTION ]

    {

        { { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] }

            [ WITH APPEND ]

            [ NOT FOR REPLICATION ]

            AS

            [ { IF UPDATE ( column )

                [ { AND | OR } UPDATE ( column ) ]

                    [ ...n ]

            | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )

                    { comparison_operator } column_bitmask [ ...n ]

            } ]

            sql_statement [ ...n ]

        }

    }

     

    * ON Table - A tabela para o qual o trigger será disparado;

    * FOR - Seguido do tipo de comando que acionam o trigger;

    * AFTER - determina que o trigger somente será disparado quando todas as rotinas especificadas no comando de disparo forem executadas com sucesso (mais utilizado)

    * INSTEAD OF - Determina que o trigger será executado ao invés do comando de disparo do mesmo.

    * [ DELETE ] [INSERT] [UPDATE] - indicam qual tipo de operação que o trigger irá disparar.

    April 30

    Hierarchyid no SQL Server 2008

    Olá, Boa noite

    Antes de chegar ao assunto conforme tem no título gostaria de lembrar á vocês que temos alguns outros novos tipos de dados conhecidos como datetime2, date, time, datetimeoffset o qual é utilizado para se trabalhar com tempo, temos no SQL Server 2008 um novo tipo de dado conhecido como hierarchyid o qual representa uma estrutura de uma hierarquia robusta através de uma tabela, sendo assim cada linha dessa tabela representa um nó da árvore.
    O tipo de dados hierarchyid nos permite trabalharmos com a extensão TRANSACT-SQL (T-SQL) podendo assim invocar métodos arbitrários como, por exemplo: insert, modify e delete em algum desses pontos utilizar esses métodos pode ser muito eficiente.
    Podemos também utilizar o tipo de dados hierarchyid em aplicações que envolva SQL Common Language Runtime (CLR), sendo assim em aplicações .NET é conhecido como SqlHierarchyID que está dentro do namespace Microsoft.SqlServer.Types. Este namespace está contido dentro do assembly Microsoft.SqlServer.Types.dll o qual pode ser encontrado dentro da janela a qual refere-se ao botão Add References , nesse caso o hierarchyid representa um valor armazenado como binário (binary) o qual pode suportar virtualmente ilimitados números de nó.


    Definindo uma estratégia de índices.

    Ao trabalharmos com o tipo de dados hierarchyid seria útil implementarmos uma estratégia de índice para assim termos um bom desempenho em nossa aplicação diariamente, temos então duas estratégias para se trabalhar com índices.
    O Primeiro índice pode ser conhecido como 'depth-first', aonde as linhas de um subconjunto são armazenadas umas próximas das outras. Por exemplo: podemos ter um Administrador de Redes ou Administrador de Banco de dados e através desses dois Administradores podemos criar um nó ráiz para através dele ter um subconjunto.


    O Segundo índice conhecido também como 'Breadth-First', as linhas são armazenadas em cada level da hierarquia. Por exemplo: Podemos ter um Administrador de banco de dados e através dele podemos ter um Desenvolvedor em banco de dados, um analista de banco de dados, projetista de banco de dados e assim sucessivamente...
     
     
     
    Antes de entrarmos na prática gostaria um pouco de falar sobre índices, sabemos que nunca é demais estudar como os índices irão se comportar em nossa aplicação temos que dar bastante crédito nessa parte, pois é através deles que nos podem garantir tanto um bom desempenho como um mal desempenho, no caso então escolha um índice correto para satisfazer as necessidades do seu banco de dados, a figura abaixo ilustra uma pequena árvore á qual pertence á uma hierarquia.
     
     

    USE MASTER


    IF
    EXISTS (SELECT name FROM sys.databases WHERE name = 'DB_Banco3')
       DROP DATABASE DB_Banco3
     BEGIN
       CREATE DATABASE DB_Banco3
     END
    GO

    USE

    DB_Banco3
    GO

    CREATE

    TABLE TBL01
    (
          NoId hierarchyid PRIMARY KEY CLUSTERED,
          NoLevel AS NoId.GetLevel(),
          IdCliente int UNIQUE NOT NULL,
          nomeCliente varchar(20) NOT NULL,
          funcaoCliente varchar(20) NOT NULL,
    )
    GO

    -- Insercao de registro

    INSERT INTO TBL01
    (NoId, IdCliente, nomeCliente, funcaoCliente)
    VALUES
    (hierarchyid::GetRoot(), 1, 'Admin', 'Root')
    GO

    -- Percebam que a coluna Raiz me tras uma hierarquia de pastas(subconjunto)...

    SELECT NoId.ToString() as Raiz,* FROM TBL01

    -- Inserindo um registro o qual sera uma raiz principal

    DECLARE @Variable hierarchyid

    SELECT

    @Variable = NoId
    FROM TBL01
    WHERE IdCliente = 1

    INSERT INTO

     TBL01 (NoId,IdCliente,nomeCliente,funcaoCliente)
     
    VALUES (@Variable.GetDescendant(NULL,NULL),10,'Jorge','D Developer')

    SELECT

    NoId.ToString() as Raiz,* FROM TBL01

    -- Inserindo um registro a qual vai pertencer a RAIZ Developer

    DECLARE @Variable2 hierarchyid

    SELECT

    @Variable2 = NoId
    FROM TBL01
    WHERE IdCliente = 10

    INSERT INTO 

    TBL01 (NoId,IdCliente,nomeCliente,funcaoCliente)
     VALUES (@Variable2.GetDescendant(NULL,NULL),20,'Leonardo','D Developer2')

    SELECT

    NoId.ToString() as Pasta,* FROM TBL01

    -- Inserindo outro registro a qual vai pertencer a funcao Developer

    DECLARE @Variable3 hierarchyid

    SELECT

    @Variable3 = NoId
    FROM TBL01
    WHERE IdCliente = 20

    INSERT INTO

    TBL01 (NoId,IdCliente,nomeCliente,funcaoCliente)
     VALUES (@Variable3.GetDescendant(NULL,NULL),30,'Leandro','D Developer3')

    SELECT

    NoId.ToString() as Pasta,* FROM TBL01

    -- Podemos tambem visualizar a nossa raiz da qual pertence o Registro x do cliente.

    DECLARE @Variable4 hierarchyid

    SELECT

    @Variable4 = NoId
    FROM TBL01
    WHERE IdCliente = 30

    SELECT

    NoId.ToString() as Raiz,
    * FROM TBL01
    WHERE NoId.IsDescendantOf(@Variable4) = 1

    -- Podemos tambem saber qual nome principal do user(nomeCliente) e a funcao do user(funcaoCliente)

    SELECT NoId.ToString() AS Raiz, *
    FROM TBL01
    WHERE NoId = hierarchyid::GetRoot()
    GO

    -- Pequeno Procedimento o qual e responsavel para inserir valores na tabela

    CREATE PROCEDURE [dbo].[insertCliente](
    @GerenteId int,
    @ClienteId int,
    @ClienteName varchar(20),
    @Funcao varchar(20))

    AS

    BEGIN

      DECLARE @GerenciaId hierarchyid

      DECLARE @LastManagerChild hierarchyid

      DECLARE @NewEmployeeNodeId hierarchyid

    -- Pegando a hierarquia(GerenciaId) e passando para o idCliente.

    SELECT @GerenciaId = NoId
    FROM TBL01
    WHERE IdCliente = @GerenteId

      SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

      BEGIN TRANSACTION

    -- Pegando o ultimo no existente na hierarquia

          SELECT @LastManagerChild = MAX(NoId)
          FROM TBL01
          WHERE NoId.GetAncestor(2) = @GerenciaId

    -- Criando uma nova hierarquia posicionada no final da existente
         
    SELECT @NewEmployeeNodeId =
         
    @GerenciaId.GetDescendant(@LastManagerChild, NULL)

    -- Adicionando uma linha
         
    INSERT INTO TBL01
         
    (NoId, IdCliente, nomeCliente, funcaoCliente)
         
    VALUES
         
    (@NewEmployeeNodeId, @ClienteId, @ClienteName, @Funcao)

      COMMIT

    END

    -- Execute, NomeProcedure, idCliente(Existente),idClienteNOVO,nomeCliente,funcaoCliente

    EXEC insertCliente 30,40,'Felipe','D Developer4'

    SELECT

    NoId.ToString() as Pasta,* FROM TBL01

    Sabemos que o SQL Server 2008 investiu bastante na parte de desenvolvimento á qual me refiro á tipos de dados,funções,gatilhos entre outros, sendo assim nos permitindo cada vez mais termos um código bem estruturado e bem prático, todavia podemos utilizar o tipo de dados hierarchyid sempre quando tivermos um cenário baseado ao que mostrei nos primeiros exemplos,  uma observação que devemos ter sempre em mente:  utilize sempre o que você achar necessário para que atinja  o que precisa, vejo que ultimamente temos bastante coisa desnecessária em nossa aplicação que se formos pensar, levaríamos minutos ou até mesmo horas.

    []’s
    Lucas Souza
    http://www.souzalucas.spaces.live.com

    March 28

    SQL Server 2008: Table-Valued Parameters

    SQL Server 2008:

           Table-Valued Parameters (Tabelas Calculadas parametrizada)


    Boa Tarde Pessoal,

    No SQL Server 2008 foi introduzido uma nova funcionalidade conhecida como: Table-Valued Parameters (TVPs) á qual pode tanto nos fornecer um bom desenvolvimento como termos um código mais estruturado/organizado, a (TVP) é baseada em um tipo de tabela definida pelo usuário, ou melhor, (user-definied table), á qual pode ser utilizada definindo um valor e assim passando esse valor por um procedimento armazenado ou até mesmo uma função definida pelo usuário (UDFs).

    Seria útil entendermos como funciona (TVPs) para utilizar-las em certos cenários, um bom ponto de partida seria comparar-las com as variáveis de tabelas, tabelas temporárias e a CTEs, entendendo assim á diferença, a semelhança e quando devemos utilizar.

    Sabemos que tanto as tabelas variáveis como as CTEs são armazenadas em memória, reduzindo assim uma quantidade alocada no cache (RAM). Devemos que ter em mente que elas serão armazenadas na tabela temporária (tempdb). Todo cuidado é pouco quando envolve o banco de dados tempdb, pois ter um bom desempenho é fundamental para que nosso banco de dados se comporte de um modo correto.

    O poder das TVPs no SQL Server 2008 está situado á habilidade de passar os valores adequáveis para uma tabela através de um parâmetro, podendo assim ser tanto um procedimento armazenado como uma função definida pelo usuário.

    Um bom benefício ao utilizar TVPs seria criar-las e utilizar-las como um schema, após termos feito isso podemos definir o schema criado por um tipo definido pelo usuário (UDT).

    Exemplo:

    CREATE TYPE Cliente AS TABLE
    (idCliente    int,
     nomeCliente  nvarchar(50),
     idadeCliente int)

    DECLARE @Customer as Cliente

    INSERT INTO @Customer VALUES (1,'Lucas Souza',18) SELECT idCliente, nomeCliente, idadeCliente from @Customer

    Á instrução acima é um tipo de tabela definido pelo usuário com o nome Cliente á qual possui três colunas. Após termos executado essa instrução podemos agora declarar e popular através de um T-SQL, Após isto o SQL Server irá armazenar esses valores na tabela temporária (tempdb) e assim podemos até utilizar esse tipo de tabela definido pelo usuário para passar espontaneamente até por procedimentos armazenados.

     


    A imagem acima localiza as tabelas definidas pelo usuário.

    Neste último exemplo criei um procedimento armazenado o qual irá ter Uma TVP,Através da tabela definida pelo usuário iremos popular uma tabela baseada na TVP:

    CREATE TABLE tblCliente
    (
          idCliente int ,
          nomeCliente nvarchar(50),
          idadeCliente int
    )

    CREATE TYPE typeCliente AS TABLE
    (
          idCliente int,
          nomeCliente nvarchar(50),
          idadeCliente int )
     
    CREATE PROC InsertProc
    (
    @VarProc as typeCliente READONLY)
    AS

    INSERT tblCliente (idCliente,nomeCliente,idadeCliente)
    SELECT idCliente,nomeCliente,idadeCliente
             FROM @VarProc

    DECLARE @Var1 as TypeCliente

    INSERT INTO @Var1 (idCliente,nomeCliente,idadeCliente) values (1,'lucas',15)

    EXEC InsertProc @Var1
    SELECT * FROM @Var1

    Limitações:

    Algumas limitações termos que ter em mente, uma delas seria: as TVPS são apenas read-only, depois que á iniciamos devemos popular e passar-las, não se pode usar para retornar dados. Neste caso a cláusula READONLY precisa ser aplicada para TVPs em procedimentos armazenados ou então não irá ser compilado, semelhantemente ao comando OUTPUT a qual não pode ser usado desta forma, lembrando também que não se pode atualizar, inserir ou deletar a coluna com os valores das linhas das TVPs.


    []’s


    Lucas Souza
    http://www.souzalucas.spaces.live.com

    March 22

    Date e Time no SQL Server 2008

    'Entendendo os novos tipos de dados no SQL Server 2008'

    Bem, sem dúvidas o SQL Server 2008 nos trouxe excelentes novidades que somos capazes de utilizarmos no nosso dia-a-dia, certa vez ao trabalhamos com informações do tipo ‘data’ e ‘hora’ por alguns motivos precisamos armazenar apenas a ‘data’, pois a hora em algumas das circunstâncias não nos satisfazem e vice-versa. Temos no SQL Server 2008 um novo tipo de dados capaz de armazenar apenas a data e assim temos também um novo tipo de dados para armazenar apenas a hora.
    SQL Server 2008 possuí um novo tipo de dados conhecido como datetimeoffset comumente usado para nos fornecer zonas de tempo. SQL Server 2008 também possui um novo tipo de dados que é responsável por armazenar intervalos de datas maiores. No SQL Server 2005 a menor data que podermos utilizar seria de 01 Janeiro de 1753, no SQL Server 2008 temos um novo tipo de dados que é capaz de armazenar informações com a data 01 de Janeiro de 0001.

    No SQL Server 2008 temos seis tipos de dados entre data e hora sendo que alguns são novos e outros já estavam presentes em versões anteriores.

    1' datetime

    2' smalldatetime

    3' date

    4' time

    5' datetime2

    6' datetimeoffset

    O primeiro tipo de dados datetime está presente em versões do SQL Server 2000 e 2005 sendo capaz de armazenar informações de data e hora, possuindo assim um intervalo de 01 de Janeiro de 1753 á 31 de Dezembro de 9999 com a precisão de 3,33 milissegundos, por exemplo: "15/03/2009 13:05:10.333".

    O segundo tipo de dados smalldatetime também capaz de armazenar informações entre data e hora, possuindo assim um intervalo 01 de Janeiro 1900 á 06 de Junho de 2079, sendo assim possuindo uma precisão de 1 minuto, por exemplo: "15/03/2009 13:05"

    O terceiro tipo de dados date é um novo componente que está presente apenas no SQL Server 2008, sendo assim um novo tipo de dados que é capaz de armazenar apenas a data, a qual armazena valores sem que precisemos armazenar a hora (time), possuindo assim um intervalo de 01 de Janeiro de 0001 á 31 de Dezembro de 9999 com a precisão de um dia, por exemplo: "10/10/2008".

    O quarto tipo de dados time está presente também apenas no SQL Server 2008 á qual é capaz de armazenar apenas o tempo sem que tenha a precisão de armazenar a data, possuindo assim um intervalo de 00:00:00.000000 até 23:59:59.9999999 com a precisão de 100 nanosegundos (7 casas decimal) por exemplo: "18:05:15.3967363".

    O quinto tipo de dados "datetime2" está presente apenas no SQL Server 2008 armazenando assim os componentes de data e tempo, possuindo um intervalo 01 de Janeiro de 0001 á 31 de Dezembro de 9999 com a precisão de 100 nanosegundos, por exemplo: "10/02/2003 20:05:03.9683926. ( A diferença entre esse tipo de dados e datetime seria o intervalo de tempo, nesse caso datetime2 possui um intervalo maior)

    O Sexto e ultimo tipo de dados datetimeoffset está presente apenas no SQL Server 2008 sendo assim, responsável por armazenar os componentes de data e hora á respeito de zonas de tempo, possuindo assim um intervalo 01 de Janeiro de 0001 á 31 de Dezembro de 9999, com a precisão de 100 nanosegundos, por exemplo: "10/04/2008 20:03:05.9386817 +02.15. A zona de tempo possui intervalos de -14:00 á +14:00.

    Temos no SQL Server 2008 6 tipos de funções á qual é responsável por retornar a data e à hora atual do sistema, 'timestamp'.

    1' GETDATE

    2' CURRENT_DATETIME

    3' GETUTCDATE

    4' SYSDATETIME

    5' SYSDATETIMEOFFSET

    6' SYSUTCDATETIME

     

    As três primeiras funções estão presentes no SQL Server 2000 e 2005. A Função GETDATE é responsável por retornar à hora atual com a precisão de 333 segundos. A função CURRENT_TIMESTAMP é similar a função GETDATE. A função GETUTCDATE é responsável por retornar a data e a hora atual 'UTC' (Hora Universal Coordenada ou Greenwich) com a precisão de 333 segundos, derivada da hora local e do tempo da zona configurada pelo servidor aonde está localizado o SQL Server. Essas três funções acima retornam o tipo de dados datetime.

    As últimas três funções são novas e estão apenas no SQL Server 2008. A função SYSDATETIME é responsável por retornar 'timestamp' sem a zona de hora, com a precisão de 10 milissegundos. A função

    SYSDATETIMEOFFSET retorna a data e a hora UTC com a precisão de 10 milissegundos, derivada da hora atual local e a zona de tempo configurada por onde o SQL Server está sendo utilizado. A função SYSDATETIME e SYSUTCDATETIME retorna o tipo de dados "datetime2", onde SYSDATETIMEOFFSET retorna tipo de dados datetimeoffset.

    Conclusão:

    Sabemos que temos novos tipos de dados o qual podemos escolher dentre elas qual seria a melhor para a nossa aplicação, no entanto se quisermos armazenar apenas a data podemos utilizar ‘date’ e se precisarmos armazenar a hora pode considerar ‘time’, sendo assim termos que ter em mente que ao utilizarmos cada um desses tipos de dados através deles podemos ter um ganho de perfomance, pois estaríamos utilizando só o que é necessário para a nossa aplicação.

    []’s

    Lucas Souza
    http://www.souzalucas.spaces.live.com
    http://www.aprendaaprogramar.com.br

    March 01

    ‘Entendendo o tipo de instrução MERGE no SQL Server 2008’

    SQL SERVER 2008: MERGE

    A Microsoft recentemente introduziu uma nova instrução t-sql conhecida como MERGE (DML), a qual é fácil de utilizar e também pode nos trazer um bom desempenho a se comparar com grandes instruções que envolva operações T-SQL. Esse comando pode substituir inúmeras instruções do tipo INSERT, UPDATE, DELETE entre outras  se resumindo em apenas uma instrução. Podemos aplicar a cláusula MERGE em uma tabela, view ou uma consulta, irei citar abaixo algumas das situações nas quais é mais utilizada. 

    * Sincronização de dados;
    * Validação de dados;
    * Transformação de dados (DTS - extract, transform, load);
    * Quando executamos instruções do tipo INSERT, UPDATE ou DELETE da tabela fonte para a  tabela alvo.

    A instrução MERGE é composta por algumas instruções tais como: MERGE, USING, ON, WHEN MATCHED, WHEN NOT MATCHED, WHENT NOT MATCHED BY SOURCE.

    MERGE: A cláusula MERGE é responsável por especificar a tabela ou uma view a qual é o alvo das operações utilizadas pelas instruções INSERT, UPDATE, DELETE.

    USING: A cláusula USING é responsável por especificar a tabela ou a view a qual estará sendo a fonte dos dados de origem para.

    ON: A cláusula ON é responsável por especificar as condições que serão determinadas quando a tabela fonte e a tabela alvo forem especificadas na instrução MERGE.

    WHEN MATCHED:
    Esta cláusula é utilizada para trabalhar com Instruções executadas UPDATE ou DELETE que está entre a tabela fonte e a tabela alvo, quando executamos a cláusula UPDATE a condição precisa retornar apenas uma linha da tabela fonte porque a instrução MERGE não pode executar as mesmas operações DML em uma única linha dentro da tabela alvo mais de uma vez. Se a condição WHEN MATCHED retornar mais de uma linha utilizando a instrução UPDATE será retornado um ERRO. Abaixo coloquei algumas regras á qual deve ser considerada antes de utilizar-la:

    ·         As duas instruções precisam ser processadas.

    ·         Uma das instruções precisa ATUALIZAR e a outra precisa DELETAR (esta ordem não é importante nem obrigatório)

    ·         Segunda cláusula WHEN MATCH é checada apenas se a primeira não for satisfeita.

    WHEN NOT MATCHED [BY TARGET]:
    Quando utilizamos WHEN NOT MATCHED BY TARGET (BY TARGET é opcional, além disso, uma sugestão é que seja explicito e utilize) é utilizado para determinar se a linha na tabela fonte não existe na tabela alvo. É utilizado para achar as linhas que precisam ser inseridos na tabela alvo vindo da fonte.

    ·         Esta segunda cláusula WHEN MATCH é checada apenas se a primeira não for satisfeita.

    ·         Adicione está opção ao seu critério.

    WHEN NOT MATCHED BY SOURCE:
    Esta cláusula é utilizada para descobrir quais são as linhas da tabela alvo que não existe na tabela fonte. Aqui algumas regras devem obedecer usando WHEN NOT MATCHED BY SOURCE.

    ·         As duas instruções precisam ser processadas;

    ·         Uma das instruções precisa ATUALIZAR e a outra precisa DELETAR (esta ordem não é importante nem obrigatório);

    ·         A segunda cláusula é checada apenas se a primeira não for satisfeita;

    ·         A primeira cláusula é especificada ao seu critério. Se você tentar executar sem
    especificar o critério de busca da primeira cláusula, será retornado um erro.

    Após termos visto um pequeno exemplo de como funciona o operador merge e quando devemos utilizar irei criar alguns exemplos e irei explicar o funcionamento deles também.

    A Sintaxe básica do comando MERGE seria essa:

    --------------------------------------------------------------------------------------------------------------------

    USING <table_source>
    ON <search_condition>
    [WHEN MATCHED [ AND <search_condition>]
            THEN {UPDATE... | DELETE } ]
    [WHEN NOT MATCHED BY TARGET [ AND <search_condition>]
            THEN INSERT... ]
    [WHEN NOT MATCHED BY SOURCE [ AND <search_condition>]
            THEN {UPDATE... | DELETE} ]

    --------------------------------------------------------------------------------------------------------------------

    Abaixo seria o diagrama de como funciona a instrução MERGE.


    Encima dessa sintaxe irei criar alguns pequenos exemplos prático.

    Exemplo 1:

    USE AdventureWorks2008
    GO

    --tabela fonte
    IF EXISTS( SELECT NAME FROM SYS.TABLES WHERE name = 'tabela_fonte')
    DROP TABLE TABELA_FONTE
    CREATE TABLE tabela_fonte(itemNumber int, itemDesc varchar(25));
    GO

    --tabela alvo
    IF EXISTS( SELECT NAME FROM SYS.TABLES WHERE name = 'tabela_alvo')
    DROP TABLE TABELA_ALVO
    CREATE TABLE tabela_alvo(itemNumber int, itemDesc varchar(25));
    GO

    --inserindo dados na tabela fonte
    INSERT INTO tabela_fonte VALUES(1,'Item A');
    INSERT INTO tabela_fonte VALUES(2,'Item B');
    INSERT INTO tabela_fonte VALUES(3,'Item C');
    INSERT INTO tabela_fonte VALUES(4,'Item D');
    GO

    --inserindo dados na tabela alvo
    INSERT INTO tabela_alvo VALUES(5,'Item need to delete');
    INSERT INTO tabela_alvo VALUES(6,'Item need to delete II');
    INSERT INTO tabela_alvo VALUES(2,'Item need to update');
    INSERT INTO tabela_alvo VALUES(3,'Item need to update II');
    GO

    --Agora iremos implementar a função MERGE
    --INSERT,UPDATE,DELETE

    MERGE tabela_alvo AS A
    USING tabela_fonte AS I
    ON (A.itemNumber = I.itemNumber)
    WHEN MATCHED
    THEN UPDATE SET A.itemDesc = I.itemDesc
    WHEN NOT MATCHED
    THEN INSERT VALUES(I.itemNumber, I.itemDesc)
    WHEN NOT MATCHED BY SOURCE
    THEN DELETE;
    GO

    SELECT * FROM TABELA_ALVO
    SELECT * FROM TABELA_FONTE
    GO

    Explicação: Observem que os valores da tabela_alvo foram alterados porque utilizamos a tabela como alvo encima da tabela_fonte, caso o itemNumber da tabela alvo for igual da tabela fonte, irá atualizar a tabela alvo baseada na tabela fonte, se caso não for igual, irá inserir os valores baseados da tabela fonte na tabela alvo ou então por último irá deletar.

    Exemplo 2:

    Agora iremos ter uma situação aonde você irá apenas utilizar "UPDATE, INSERT" e não irá precisar deletar as linhas caso não exista ou algo do tipo. Esta e outras instruções utilizando MERGE podem ser aplicadas baseadas na tabela que criamos acima.

    -- utilizando update, insert
    MERGE tabela_alvo AS A
    USING tabela_fonte AS I
    ON (A.itemNumber = I.itemNumber)
    WHEN MATCHED
    THEN UPDATE SET A.itemDesc = I.itemDesc
    WHEN NOT MATCHED
    THEN INSERT VALUES(I.itemNumber, I.itemDesc);
    GO

    SELECT * FROM TABELA_ALVO
    SELECT * FROM TABELA_FONTE
    GO

    Exemplo 3:

    --utilizando update,delete.
    MERGE tabela_alvo AS A
    USING tabela_fonte AS I
    ON (A.itemNumber = I.itemNumber)
    WHEN MATCHED
    THEN UPDATE SET A.itemDesc = I.itemDesc
    WHEN NOT MATCHED BY SOURCE
    THEN DELETE;
    GO

    SELECT * FROM TABELA_ALVO
    SELECT * FROM TABELA_FONTE
    GO

    Exemplo 4:

    Irei mostrar nesse último exemplo como aplicar apenas a instrução UPDATE utilizando o comando MERGE, certa vez pode ser útil utilizar essa instrução em alguns cenários, um deles seria o que irei mostrar.
    Imagine que você tem duas tabelas com dados totalmente distintos e você gostaria de atualizar uma baseada na outra, por exemplo, igualar por um campo data, como você poderia fazer isto? Atualizar linha por linha? Creio que isso lhe tomará um grande tempo dependendo do volume de dados da sua tabela e, além disso, devemos está cientes que podemos até perder um pouco do desempenho do nosso banco de dados; certa vez ,quando estamos desenvolvendo uma certa aplicação sempre procuramos por um melhor desempenho e um menor trabalho, creio que, utilizando o exemplo abaixo no seu dia-dia, poderá cobrir um desses dilemas que temos freqüentemente.

    MERGE tabela_alvo AS A
    USING tabela_fonte AS I
    ON (A.itemNumber = I.itemNumber)
    WHEN MATCHED
    THEN UPDATE SET A.itemDesc = I.itemDesc;
    GO

    SELECT * FROM tabela_alvo
    SELECT * FROM tabela_fonte;
    GO

    Conclusão

    Concluímos este artigo explicando o funcionamento da instrução MERGE sabendo que, podemos utilizá-lo combinando com certos operadores tais como: INSERT, UPDATE, DELETE e quando devemos utilizar em nosso cenário. Quem trabalha como desenvolvedor ou até mesmo DBA creio que utilizando o operador MERGE nas suas consultas irá se tornará bastante útil, pois a maioria dos bancos de dados que se tornam altamente fragmentados ou até mesmo ‘lento’ são por causa de instruções mal feitas ou algo relacionado a T-SQL. Temos sempre que está ciente qual das melhores alternativas podemos utilizar para deixar o nosso banco de dados agradável ao cliente e como ele poderá utilizar-lo da forma mais fácil.

    Seya!
                   

    February 12

    SQL Server 2008: Melhorias em T-SQL Parte 04

    GROUPING SETS

     

    Olá, pessoal, sem dúvidas, a respeito de T-SQL, o SQL Server 2008 nos trouxe a mais uma excelente funcionalidade conhecida como GROUPING SETS.

     

    O GROUPING SETS é um grupo de instruções utilizado para obter um certo resultado, por exemplo: ao invés de utilizarmos o conhecido UNION ALL para nos trazer a união de vários campos calculados, você poderá agora utilizar o GROUPING SETS, pois, você terá um melhor ganho de desempenho; há também outras funcionalidades para trabalhar juntamente com o GROUPING SETS, por exemplo: CUBE, ROLLUP e outras que serão apresentadas em breve.

     

    Algumas considerações:

     

     * GROUPING SETS são funções que ajudam a chegar rapidamente em um ponto com resultados esperados e, juntamente com ele, pode-se utilizar funções como: AVG, SUM, MAX, MIN entre outras;

     

     * Dependendo da consulta, GROUPING SETS podem obter um melhor desempenho quando comparado com o UNION ALL;

     

     * Podem obter também um melhor desempenho para executar instruções de outras fontes de dados;

     

    Essa característica é excelente principalmente para desenvolvedores, é como o MERGE, que é outra funcionalidade do SQL Server 2008 que será assunto nos próximos artigos, é possível obter uma soma, um valor máximo ou um valor mínimo, utilizando uma  única instrução.

     

    Isso está sendo mostrado nos códigos abaixo: 

    USE master

    -- Se existir algum banco de dados cujo nome é 'DB_TESTE', Delete.

    IF EXISTS(SELECT name FROM sys.databases WHERE name = 'DB_TESTE')
    DROP DATABASE DB_TESTE

    -- Criação do banco;

    CREATE DATABASE [DB_TESTE]

    -- Se posicionando no banco criado

    USE [DB_TESTE]

    -- Se existir alguma tabela cujo nome é 'DB_TSQL', Delete.

    IF EXISTS(SELECT name FROM sys.tables WHERE name = 'DB_TSQL')
    DROP DATABASE DB_TSQL

    -- Criação da tabela

    CREATE

    TABLE DBO.TBL01
    (
    ID INT
    ,
    NOME NVARCHAR(60
    ),
    VALOR SMALLMONEY
    ,
    DATANASC
    DATETIME
    )

    -- Inserindo alguns valores

    INSERT dbo.TBL01 VALUES (1,'LUCAS',20,GETDATE()),(2,'THIAGO',30,GETDATE()),(3,'JOÃO',40,GETDATE()),
    (4,'PEDRO',50,GETDATE()),(5,'RAFAEL',60,GETDATE()),(6,'GUSTAVO',70,GETDATE
    ()),
    (7,'RODRIGO',80,GETDATE()),(8,'JEFERSON',90,GETDATE()),(9,'DIEGO',100,GETDATE())

    -- Selecionando todos os campos, sem utilizar o GROUPING SETS.

    SELECT * FROM DBO.TBL01

    -- no SQL Server 2005 no se quisermos pegar mais de um valor em mais de uma consulta, teriamos que utilizar por exemplo o UNION ALL

    SELECT AVG(ID) FROM TBL01
    UNION
    ALL
    SELECT COUNT(NOME) FROM
    TBL01
    UNION
    ALL
    SELECT SUM(VALOR) FROM TBL01

    -- o SQL Server 2008 pode nos facilitar isso agora desta forma:

    SELECT AVG(ID),COUNT(NOME),SUM(VALOR)
    FROM
    DBO.TBL01
    GROUP BY GROUPING SETS
    (
    (
    ID
    ),
    (
    NOME
    ),
    (
    VALOR
    ),
    ()
    )

    SELECT

    TOP 2 MAX(DATANASC) FROM
    DBO.TBL01
    GROUP BY GROUPING SETS
    (
    (
    DATANASC
    ),
    ()
    )
     
     

    []'s
    Lucas Souza

    February 05

    SQL Server 2008: Melhorias em T-SQL Parte 03

    Object Dependencies Improvement

    Quem trabalha com SQL Server 2005 esse nome provavelmente não é novidade, pois foram acrescentadas mais algumas delas no SQL Server 2008. É um recurso que provê uma melhor busca entre objetos através de catálogos tanto introduzidos em view quanto em dynamic management functions. Essas dependências são sempre referenciadas por nome do Schema, referência da entidade, nome do servidor entre outras e são seguidas por: stored procedures, tables, functions,triggers, user-definied types, xml schema-collections entre outros. O SQL Server 2008 introduziu novos objetos como:

    sys.sql_expression_dependencies (Catalog View)

    sys.dm_sql_referenced_entities (DMF)  

    sys.dm_sql_referencing_entities (DMF)

    Pode-se visualizar as dependências por dois meios, um deles é usando a interface gráfica, Clique no botão direito em uma tabela e selecione: View Depedencies, como mostrado na imagem a seguir:

     

    E o outro seria via T-SQL:

    USE
    tempdb;
    GO

    IF

    OBJECT_ID('dbo.Tabela1','U') IS NOT NULL
    DROP TABLE dbo.Tabela1
    GO

    IF

    OBJECT_ID('dbo.MinhaView','V') IS NOT NULL
    DROP VIEW dbo.MinhaView
    GO

    CREATE

    TABLE dbo.Tabela1
    (
    Col1 INT,
    Col2 INT
    )
    GO

    CREATE

    VIEW dbo.MinhaView as
    SELECT Col1,Col2 FROM dbo.Tabela1
    GO

    SELECT

    OBJECT_NAME(referencing_id) as referecing_entity_name,
    referenced_server_name as server_name,
    referenced_database_name as database_name,
    referenced_schema_name as schema_name,
    referenced_entity_name
    FROM sys.sql_expression_dependencies
    WHERE referencing_id = OBJECT_ID(N'dbo.MinhaView');
    GO

    SELECT

    referenced_schema_name as objschema,
    referenced_entity_name as objname,
    referenced_minor_name as minorname,
    referenced_class_desc as class
    FROM sys.dm_sql_referenced_entities('dbo.MinhaView','OBJECT');
    GO

    SELECT

    referenced_schema_name as objschema,
    referenced_entity_name as objname,
    referenced_class_desc as class
    FROM sys.dm_sql_referenced_entities('dbo.MinhaView','OBJECT');
    GO

    Seya

    []'s

    Lucas Souza
    http://www.souzalucas.spaces.live.com
    http://www.aprendaaprogramar.com.br

    January 25

    SQL Server 2008: Melhorias em T-SQL Parte 02

    Serão mostradas aqui algumas melhorias que estão presentes no SQL Server 2008 a respeito de declaração de variáveis.

    SQL Server 2005:

    DECLARE

    @VAR1 INT
           
    SET @VAR1 = 2

    SQL Server 2008:

    DECLARE @VAR1 INT = 5
    DECLARE @VAR2 INT = 10

    DECLARE @VAR3 INT = @VAR1 * @VAR2
       
    PRINT @VAR3

     

    As variáveis podem ser inicializadas no momento da declaração, ou seja, nas mesmas linhas declarando o valor logo após a instrução DECLARE sem utilizar o operador SET. Vários tipos de dados podem ser utilizados, inclusive o SQLCR, mais não será possível variáveis do tipo TEXT, NTEXT ou IMAGE.

    Operadores

    Esses operadores se encontram presentes nas linguagens C#, C++ entre outras, a vantagem de utilizar-los no SQL Server 2008 é evitar mau desempenho, manter o código mais legível dentre outras vantagens. Abaixo segue a lista dos operadores.

    +=
    -=
    *=
    /=
    %=
    &=
    ^=
    |=

    -- Declarando primeira variável


    DECLARE
    @VAR10 INT = 10

    -- Declarando segunda variável

    DECLARE @VAR11 INT = 11

    -- Declarando terceira variável e atribuindo nela algumas variáveis


    DECLARE
    @VAR12 INT = @VAR10 * @VAR11

    -- Declarando quarta variável e logo após trabalhando com o operador +=


    DECLARE
    @VAR13 INT = 15
    SET @VAR12 += @VAR13
    SELECT
    @VAR12 as 'ValorFinal'

     

    Seya

    []'s

    Lucas Souza
    http://www.souzalucas.spaces.live.com
    http://www.aprendaaprogramar.com.br

    January 24

    SQL Server 2008: Melhorias em T-SQL Parte 01

    SQL Server 2008 introduziu excelentes melhorias para ter uma melhor produtividade tanto para "desenvolvedores" como "administradores" reduzindo tempo de  gasto utilizado para desenvolver certas aplicações utilizanto T-SQL. Uma delas é o Intellisense sem dúvida é um recurso fantástisco, essa caracteristica trabalha automáticamente com checagem de sintaxe igual ao Visual Studio 2008, como vocês podem ver na imagem abaixo o uso dela:

      

    Lembrando que essa funcionalidade não está disponivel para SQL Server 2000 nem 2005 apenas no SQL Server 2008

    Seya!