segunda-feira, 31 de janeiro de 2011

Tutorial para iniciantes em SQL Server

A Microsoft disponibiliza, através do portal TechNet, diversos recursos de aprendizado para o SQL Server e várias outras tecnologias desenvolvidas por ela.

Para os que estão começando, existe um tutorial bastante completo sobre as operações mais comuns utilizadas em implementações e acesso a banco de dados.


O material está em inglês e é baseado em 3 lições principais:
  
- Lesson 1: Creating Database Objects - Aprenda a criar um Bancos de Dados, Tabelas e inserir/consultar dados.
- Lesson 2: Configuring Permissions on Database Objects - Aprenda como criar logins, definir pemissões. Veja também como implementar views e stored procedures, para acessar os dados armazenados no banco e controlar o acesso através de permissões.
- Lesson 3: Deleting Database Objects - Exclua dados de tabelas, objetos do banco (tabelas, procedures e views) e também o próprio banco de dados.
É uma ótima boa de iniciar o aprendizado.
Vale a pena conferir!

Estudo de caso: McLaren Electronic Systems

Para os que acham que o SQL Server não é capaz de atender aplicações de alta performance, aqui vai um exemplo prático...

Neste artigo, a Microsoft, em parceria com a equipe da McLaren, mostra o SQL Server trabalhando como banco de dados para uma aplicação de monitoramento e coleta de dados dos carros de Formula 1 da equipe durante os testes, treinos e corridas.

Esta aplicação exige uma alta performance do banco de dados, pois o volume de dados coletados é muito alto. Segundo o artigo, são gerados entre 1 e 2 Gigabytes de dados em uma corrida e, ao longo de um ano, são gerados entre 2 e 3 Terabytes!

Confira o texto completo (em inglês) e assista também ao vídeo disponibilizado com o artigo:

Microsoft Case Studies: McLaren Electronic Systems

Abraços!

Verificando se uma coluna existe em uma tabela (através de Views de Sistema)

As Views de Sistema são ferramentas muito úteis para recuperar informações sobre a estrutura e estatísticas de um banco de dados SQL Server.

Os scripts abaixo mostram como utilizar a view COLUMNS do Schema INFORMATION_SCHEMA para verificar se uma coluna existe. Nos exemplos, deseja-se incluir a coluna Telefone VARCHAR(15) à tabela Funcionarios a View Columns é utilizada para verificar se a coluna já pertence à tabela, evitando que o script resulte em erro (por tentativa de inserção de uma coluna duplicada).

Veja o exemplo para as versões 2005 e 2008 do SQL Server:

-- Criando tabela para teste
CREATE TABLE Funcionarios
(
    idFuncionario INT IDENTITY (1,1) PRIMARY KEY
    , nome VARCHAR(100) NOT NULL
)

-- Verificando se a coluna Telefone VARCHAR(15)
-- existe na tabela Funcionarios
IF NOT EXISTS
(
  SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS C
  WHERE
    TABLE_NAME = 'Funcionarios'
    AND TABLE_SCHEMA = 'dbo'
    AND COLUMN_NAME = 'Telefone'
    AND DATA_TYPE = 'VARCHAR'
    AND CHARACTER_MAXIMUM_LENGTH = 15
)
BEGIN

   -- Adicionando a coluna Telefone VARCHAR(15)
   -- à tabela Funcionarios
   ALTER TABLE Funcionarios
      ADD Telefone VARCHAR(15)

   PRINT 'Coluna Telefone adicionada à tabela Funcionarios'

END
ELSE
   BEGIN
     PRINT 'Coluna Telefone já existe na tabela Funcionarios'
   END

Para os que utilizam o SQL Server 2000, pode-se utilizar um conjunto de Views de Sistema (sysobjects, syscolumns e systypes) para obter resultado semelhante.Veja o exemplo abaixo:

-- Criando tabela para teste
CREATE TABLE Funcionarios
(
    idFuncionario INT IDENTITY (1,1) PRIMARY KEY
    , nome VARCHAR(100) NOT NULL
)

-- Verificando se a coluna Telefone VARCHAR(15) existe na tabela Funcionarios
IF NOT EXISTS 
(
    SELECT 1 FROM syscolumns Coluna
        INNER JOIN sysobjects    Tabela ON
             Coluna.id     = Tabela.id
        INNER JOIN systypes        Tipo ON
             Tipo.xtype = Coluna.xtype
    WHERE
            Coluna.name        = 'Telefone'
        AND Tabela.name        = 'Funcionarios'
        AND Tipo.name        = 'varchar'
        and Coluna.length    = 15
)
BEGIN
 
    -- Adicionando a coluna Telefone VARCHAR(15)
    -- à tabela Funcionarios
    ALTER TABLE Funcionarios
        ADD  Telefone VARCHAR(15)
     
    PRINT 'Coluna Telefone adicionada à tabela Funcionarios'
     
END
ELSE
    BEGIN
        PRINT 'Coluna Telefone já existe na tabela Funcionarios'
    END

Nestes exemplos, comparamos o nome, tipo de dado, e tamanho do campo para encontrar a coluna. As view de sistema disponibilizam muitas outras informações (collation, precisão decimal, etc.). Explore estas informações de acordo com a sua necessidade!

terça-feira, 25 de janeiro de 2011

Inserindo o resultado de uma consulta em uma tabela já existente

No artigo anterior, verificamos como inserir os resultados de uma consulta em uma nova tabela utilizando a cláusula INTO do comando SELECT. Agora, vamos explorar como inserir o resultado de uma consulta em uma tabela já existente.

O comando INSERT possui uma sintaxe alternativa que auxilia a execução desta tarefa. Veja abaixo:

INSERT INTO tabelaDestino
SELECT campo1, campo2, ... , campoN
FROM tabelaOrigem
WHERE condicionais

Utilizando a tabela Funcionarios do artigo anterior, criaremos

CREATE TABLE Funcionarios
(
    idFuncionario INT IDENTITY (1,1) PRIMARY KEY
    , nome VARCHAR(100) NOT NULL
    , dataAdmissao DATETIME NOT NULL
    , dataDemissao DATETIME NULL
)

-- Inserindo dados fictícios para testes
INSERT INTO Funcionarios VALUES
    ('Evandro', '2001-07-03', NULL)
    ,('José','2002-02-09',NULL)
    ,('Ronaldo','1995-09-25','2001-05-03')
    ,('Márcia','2003-03-22','2004-06-04')
    ,('Régis','1997-09-25','2004-08-07')
    ,('Renata','2008-02-27',NULL)
    ,('Mariana','2009-01-15',NULL)

Em seguida, criaremos a tabela para armazenar os funcionários demitidos (FuncionariosDemitidos), com a mesma estrutura da tabela Funcionarios

-- Criando a tabela de Funcionários demitidos com a mesma estrutura original
CREATE TABLE FuncionariosDemitidos
(
    idFuncionario INT
    , nome VARCHAR(100) NOT NULL
    , dataAdmissao DATETIME NOT NULL
    , dataDemissao DATETIME NULL
)

Para preencher a nova tabela, basta utilizar o comando INSERT com a sintaxe indicada:

-- Inserindo os dados dos funcionários demitidos
INSERT INTO FuncionariosDemitidos      
    SELECT *
    FROM Funcionarios
    WHERE
        dataDemissao is not null

Algumas consideraçõe sobre este procedimento:
  • Ao contrário do comando SELECT com a cláusula INTO, o comando INSERT não cria a tabela tabelaDestino. Ou seja, a tabela tabelaDestino precisa obrigatoriamente existir.
  • Evite utilizar o caracter curinga * para definir os campos a serem inseridos na tabela tabelaOrigem, principalmente quando esta possuir campos com auto-numeração (IDENTITY)

Para maiores informações sobre o comando INSERT, consulte no MSDN:
INSERT (T-SQL)

Inserindo o resultado de uma consulta em uma nova tabela

Esta é uma tarefa simples, muito utilizada para fazer backup de tabelas ou extrair dados segundo um filtro.

Se a tabela ainda não existir, pode-se utilizar a cláusula INTO do comando SELECT para inserir os resultados em uma nova tabela com as mesmas colunas definidas no retorno do comando SELECT.

Para exemplificar, criaremos uma tabela simples para simular o cadastro de funcionários de uma empresa:

CREATE TABLE Funcionarios
(
    idFuncionario INT IDENTITY (1,1) PRIMARY KEY
    , nome VARCHAR(100) NOT NULL
    , dataAdmissao DATETIME NOT NULL
    , dataDemissao DATETIME NULL
)

-- Inserindo dados fictícios para testes
INSERT INTO Funcionarios VALUES
    ('Evandro', '2001-07-03', NULL)
    ,('José','2002-02-09',NULL)
    ,('Ronaldo','1995-09-25','2001-05-03')
    ,('Márcia','2003-03-22','2004-06-04')
    ,('Régis','1997-09-25','2004-08-07')
    ,('Renata','2008-02-27',NULL)
    ,('Mariana','2009-01-15',NULL)

Veja abaixo como o comando SELECT (com a cláusula INTO) pode ser utilizado para extrair os funcionários demitidos de uma empresa (Data de demissão preenchida) e armazená-los em uma nova tabela FuncionariosDemitidos:

-- Criando tabela com os funcionários demitidos
SELECT *
INTO FuncionariosDemitidos
FROM Funcionarios
WHERE
    dataDemissao is not null 

Observe o resultado de uma consulta sobre a nova tabela FuncionariosDemitidos:

 

Observe que apenas as linhas com a coluna DataDemissao preenchida foram inseridas na nova tabela.

Além disso, o nome dos campos criados na nova tabela são idênticos aos da tabela original.

Para maiores sobre a cláusula INTO do comando SELECT, consulte no MSDN: 
INTO Clause (Transact-SQL)

segunda-feira, 10 de janeiro de 2011

Criando scripts parametrizáveis

Scripts dinâmicos são aqueles criados em tempo de execução de uma consulta do SQL Server e são importantes ferramentas para tornar o desenvolvimento mais flexivel e muitas vezes mais otimizado.

Assim como acontece com as Stored Procedures, o SQL Server permite a criação dinâmica de batches parametrizáveis, isto é, pode-se criar scripts que recebem valores através de parâmetros. Scripts de manutenção, ou de consulta mais complexos (aqueles que não pertencem a sistemas e também convém encapsular em stored procedures) podem ser executados dessa forma. 
Utilizaremos a stored procedure de sistema sp_executesql para  realizar esta tarefa, muito conhecida para a execução de scripts armazenados em strings. A sintaxe utilizada será:

exec sp_executesql @script, @params, @param1, @param2, ... @paramN

Neste caso, @script é uma string contendo o conteúdo do script, @paramsé uma string contendo os nomes e tipos dos parâmetros, e os parâmetros @param1, @param2, ... @paramN representam os N parâmetros definidos em @params.

O exemplo abaixo mostra como parametrizar um script no SQL Server:

 /* Declarando os parâmetros e seus respectivos tipos */
DECLARE @vars NVARCHAR (100)
SET @vars = '@valor CHAR(30)'

/* Declarando o conteúdo do script, utilizando o parâmetro definido acima */
DECLARE @script NVARCHAR(100)
SET @script = 'PRINT ''Exibindo o valor do parâmetro: '' + @valor'

/* Executando o script passando o parâmetro declarado */
exec sp_executesql @script, @vars, '$valor$'

Na figura abaixo, observamos o script acima em execução. Observe que o valor passado foi utilizado durante a execução do script:


Observações:
  • A stored procedure sp_executesql pode rodar apenas um batch por execução, ou seja, não é possível adicionar o comando "GO" ao script passado por parâmetro.