Table-Valued Parameters – Utilizando o tipo de dados tabela

Em versões anteriores ao SQL Server 2008 não é possível utilizar tabelas como parâmetro de Stored Procedures. Quando temos de enviar múltiplos dados para o banco de dados, acabamos por enviar tais dados um de cada vez, linha por linha, orientados por um laço de repetição. O SQL Server 2008 proporciona um contorno para esta solução através do uso de Table-Valued Parameters. Os Table-Valued Parameters permitem a passagem de tabelas como parâmetro para Stored Procedures.

Para a utilização deste recurso é necessário seguir um conjunto de passos, vou enumerá-los a seguir:

1 – Tipo dados de tabela

A primeira coisa a se fazer é criar um tipo de dados de tabela (table type). Para a criação deste tipo de dados deve-se utilizar a seguinte sintaxe.

CREATE TYPE dbo.PointAttention AS TABLE
(
Id int NOT NULL,
Description varchar(100) NOT NULL,
Date datetime NOT NULL,
PRIMARY KEY (Id)
)
GO

2 – Trabalhando com o tipo de dados de tabela

Para utilizar este tipo de dados, na sintaxe Transaction-SQL, é preciso criar uma variável deste tipo de dados e então valorizá-la como se fosse uma tabela.

DECLARE @varPoint PointAttention

INSERT INTO @varPoint(Id,Description,Date)
VALUES (100,’Alerta de segurança 1′,’2011-01-20′),
(101,’Alerta de segurança 2′,’2011-01-20′),
(102,’Alerta de segurança 3′,’2011-01-20′),
(103,’Alerta de segurança 4′,’2011-01-20′),
(104,’Alerta de segurança 5′,’2011-01-20′)

SELECT * FROM @varPoint

Assim como qualquer outra tabela, variáveis desse tipo podem ser utilizadas para popular outras tabelas ou servirem em clausulas JOIN dentro de comandos de seleção.

* Observação: por ser uma variável, será limpa da memória automaticamente assim que o escopo de execução for concluído, não consumindo recursos além daqueles necessários durante seu bloco de execução.

3 – Utilizando tipos de dados tabela como parâmetro de Stored Procedures

Agora vamos ao ponto focal deste texto, que é receber uma estrutura de tabela como parâmetro de uma Stored Procedure.

Para execução do exemplo, criemos uma tabela que possua uma estrutura semelhante a do nosso tipo de dados tabela.

CREATE TABLE dbo.tbPointAttention
(
pntId int NOT NULL PRIMARY KEY,
pntDescr varchar(20) NOT NULL,
pntDate datetime NOT NULL
)
GO

Agora, para construção da Stored Procure mantemos a mesma sintaxe, apenas incluindo um parâmetro com o mesmo tipo de dados de tabela criado anteriormente.

CREATE PROC spInsertPAttention @PAttentions PointAttention READONLY
AS
INSERT INTO tbPointAttention
(pntID, pntDescr, pntDate)
SELECT ID,Description,Date
FROM @PAttentions
GO

4 – Consumindo tipos de dados tabela através de aplicações .Net

O ponto chave de utilização deste novo tipo de estrutura é a utilização do tipo de dado SqlDbType.Structured (presente no namespace System.Data.SQLClient, disponível a partir do Microsoft .Net Framework 3.5).

O exemplo abaixo demonstra como essa interação pode ser codificada utilizando C#.

Capturar

 

Vantagens da utilização de Table-Valued Parameters:
– Simplificação da lógica do projeto;
– Permite aos desenvolvedores construírem aplicações performáticas;

Referências:
http://msdn.microsoft.com/en-us/library/bb510489.aspx
http://msdn.microsoft.com/en-us/library/bb675163.aspx
http://www.sqlteam.com/article/sql-server-2008-table-valued-parameters

 

Por
Fernando Henrique Inocêncio Borba Ferreira.

Publicidade

Linq to SQL – Atributos de Mapeamento Objeto-Relacional

Quando trabalhamos com LINQ to SQL nosso mapeamento objeto-relacional pode ser construído de duas maneiras: através de um arquivo externo (XML Mapping Source) ou através do mapeamento das classes da aplicação (Attribute Mapping Source). Na grande maioria dos casos acabamos por realizar o mapeamento dos atributos das classes da aplicação e utilizamos o Object Relational Designer – assistente do Microsoft Visual Studio que gera o mapeamento do banco de dados automaticamente para nossa aplicação.

O mapeamento ocorre da seguinte maneira:
– O banco de dados é mapeado para uma instância de um DataContext.
– Uma tabela é mapeada para uma classe
– As colunas da tabela são mapeadas para as propriedades das classes

Podemos construir esse mapeamento manualmente, sem utilizar o assistente do Microsoft Visual Studio, a fim de tornar o código mais simples, gerenciável e inteligível. Para tanto devemos fazer uso dos atributos de mapeamento do LINQ, tais atributos estão contidos no namespace System.Data.Linq.Mapping. Para ter acesso a esses atributos precisamos fazer referência a dll System.Data.Linq.

O mapeamento de uma tabela vai se parecer com o código a seguir:

Mapclasses

… baseado na estrutura da seguinte tabela:

clip_image003

Comparando o código C# e o código SQL, podemos considerar alguns pontos:
– O atributo Table, localizado acima da definição da classe Customer, indica que esta classe corresponde ao mapeamento de uma tabela, mais especificamente a tabela tbMappingCustomer, especificada pelo valor definido na propriedade Name .

– O atributo Column indica que uma propriedade corresponde a uma coluna da tabela, isto é, o atributo Column simboliza o mapeamento entre uma coluna da tabela e uma propriedade da classe.

– O atributo Column possui diversas propriedades Name e CanBeNull são apenas algumas, mas são algumas das principais. Em um próximo post discutiremos outras possibilidades. A propriedade Name do atributo Column indica qual coluna da tabela deverá ser mapeada pelo LINQ to SQL, e a propriedade CanBeNull indica quais colunas aceitam valores nulos na base de dados.

– As propriedades IsDbGenerated e IsPrimaryKey são propriedades do atributo Column, que são utilizadas apenas na propriedade ID, pois essa propriedade mapeia a chave primária da tabela. A propriedade IsDbGenerated indica que o atributo possui valores gerados pelo próprio banco de dados, no nosso caso os valores dessa coluna da tabela são gerados automaticamente pelo Identity(1, 1) citado no código SQL. A propriedade IsPrimaryKey é autoexplicativa, ela indica se a propriedade corresponde ao mapeamento da chave primaria da tabela.

Para persistir as informações é preciso utilizar um objeto que faça a ponte entre a aplicação e o banco de dados, este objetivo é o DataContext. A função do DataContext é traduzir o mapeamento objeto-relacional para comandos que possam ser interpretados pelo banco de dados, assim como converter os dados retornados pelo banco de dados para as entidades do mapeamento objeto-relacional.

No caso, costumo criar uma classe que herde de um DataContext, e que para cada tabela, crie-se um atributo do tipo Table<E> que referencie uma entidade mapeada para a aplicação. Na imagem abaixo demonstro como faço essa implementação.

DataContext

Abaixo um exemplo de como unir a utilização do DataContext customizado, com as entidades mapeadas manualmente.

Implementacao

Obrigado.
[]s!

Referências indicadas:
http://oreilly.com/catalog/9780596519254
http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.aspx
http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/09/23/24907.aspx
http://msdn.microsoft.com/en-us/library/bb386971.aspx