Com o lançamento do Microsoft SQL Server 2005, passamos a conhecer uma nova ferramenta, que veio com o propósito de incluir a Microsoft como um dos grandes players do Mercado, no que diz respeito ao universo de BI (Business Inteligence). Desta forma, passamos a falar do Microsoft SQL Server Integration Services (também conhecido como SSIS).

Desde 2005 para cá, particularmente eu posso falar que a Ferramenta amadureceu o suficiente para se destacar frente a outras demais ferramentas de ETL (Extract, Transform and Load – Extrair, Transformar e Carregar).

Este processo diz respeito a unificar informações de Bases de Dados transacionais, que são informações que estão em nossas bases de dados e que são gravados pelos Sistemas desenvolvidos em .NET, Java, Delphi e etc., e enviá-las para uma base de dados histórica, sendo esta conhecida como Data Warehouse (DW). Esta base é modelada de uma forma diferente da qual conhecemos, sendo que as Bases de Dados Transacionais pregam a ideia de Normalização dos Dados e a base de Dados do Data Warehouse (DW), trabalha com a ideia de “desnormalização” destes dados.

Em siglas, esta diferença pode ser considerada ao falarmos dos ambientes OLTP (Online Transaction Processing) e OLAP (Online Analytical Processing).Mas o intuito deste artigo não é falar especificamente sobre a Arquitetura que envolve um processo de BI (onde a Microsoft possui uma suíte completa de ferramentas) e sim, apresentar como o Microsoft SSIS (SQL Server Integration Services) se encaixa dentro desta arquitetura.

Estou utilizando a Versão do Microsoft SQL Server 2012, que quando instalado cria um Shell do Microsoft Visual Studio na versão 2010, que possibilitará trabalharmos com projetos do Integration Services.

Aqui no micro que estou preparando este artigo, possuo a versão do Microsoft Visual Studio 2010 completo.

Template de Projetos do Integration Services no Shell do Visual Studio 2010

Figura 1: Template de Projetos do Integration Services no Shell do Visual Studio 2010

Porém, mesmo utilizando o Visual Studio e tendo o Microsoft SQL Server (versões 2005, 2008/2008 R2 e 2012) instalados no micro de Desenvolvimento, muitos dos colegas que trabalham com estas plataformas não utilizam as ferramentas instaladas. Mesmo os colegas que estão iniciando no universo de BI com a plataforma da Microsoft, se perguntam como fazer atividades como: Utilizar IF, ELSE no Integration Services.

Um Projeto do Integration Services aberto no Visual Studio 2010

Figura 2: Um Projeto do Integration Services aberto no Visual Studio 2010

Bom, vamos iniciar nosso exemplo deste artigo.

Antes de mais nada, aos colegas que não conhecem o SSIS, prepararei logo mais um artigo específico para apresentar outros detalhes da Ferramenta.

Com o Visual Studio aberto, iniciaremos nosso estudo criando um projeto do Integration Services, dando para o mesmo o nome de:Usando DOT_NET_SSIS.

No SQL Server 2012, temos o Banco de Dados AdventureWorks e a tabela Product, que será utilizada para nosso artigo.

Na tela principal temos Abas, onde cada uma delas possui uma Funcionalidade Específica, de acordo com cada Aba selecionada. A Figura 3 apresenta com detalhe a Aba inicial Control Flow com seus respectivos Itens da ToolBox.

Aba Control Flow do Visual Studio com seus respectivos Itens da ToolBox

Figura 3: Aba Control Flow do Visual Studio com seus respectivos Itens da ToolBox

Bom, a ideia do artigo é apresentar a utilização do Item Execute SQL Task para selecionarmos alguns produtos da Tabela Product do Banco AdventureWorks, no qual trabalharemos com produtos que possuam a Lista de Preços de valores entre 50 e 100 (Dólares, Reais ou qualquer outra, como quiserem).

Porém, para pegarmos estes registros da Tabela de Produtos, temos primeiro que nos conectar no Banco e após, fazermos este Select.

O Item Execute SQL Task ao ser anexado nos fornece a opção de conectarmos ao Banco de dados do SQL Server, conforme apresentado na Figura 4.

Adicionando o Execute SQL Task para executar o Script no Banco de Dados

Figura 4: Adicionando o Execute SQL Task para executar o Script no Banco de Dados

Para nosso exemplo, criei uma conexão no qual posso utilizar em todo o Projeto, ou seja, uma conexão Global. A Figura 5 abaixo demostra o lugar onde a mesma fora criada.

Criando uma conexão Global para o projeto

Figura 5: Criando uma conexão Global para o projeto

Em sequência, criei o seguinte Script abaixo para realizar tal tarefa, onde este Script retorna todos os registros dentro da Tabela, conforme a Figura 8 apresenta.

Listagem 1: Script para listar todos os registros da tabela Product

SELECT * FROM Production.Product
Retorno da Execução da Query apresentada no Script, dentro do SQL Server 2012

Figura 6: Retorno da Execução da Query apresentada no Script, dentro do SQL Server 2012

A consulta retorna 504 registros onde a ideia do artigo será exportarmos Produtos com os valores menores que 100 para um arquivo TXT específico e os Produtos de valores maiores para um segundo arquivo TXT.

Para a consulta que retorna Produtos com valores de Lista de preço menores que 100, gravaremos no arquivo ProdutoMenor100.txt, onde os Produtos com Lista de preço maior que 100, serão gravados no arquivo ProdutoMaior100.txt (por conveniência particular, vou gravar ambos os arquivos no Disco C:\).

Bom, vamos voltando ao nosso exemplo.

No Visual Studio, após incluirmos o Item Execute SQL Task, incluiremos também mais um Item: o Script Task. Este item nos possibilita trabalharmos com código .NET (seja C# ou VB .NET), para podermos incluir em nossa rotina algum fluxo desenvolvido em uma destas linguagens. Imaginem vocês que para validarmos algum processo de nossa regra de negócio, necessitaríamos, por exemplo, consumir uma DLL desenvolvida em .NET ou um método em Webservice ou WCF. Com este item, poderemos adicionar tal funcionalidade.

Com isso, arraste o Item Script Task, que nesta versão do Integration Services dentro do Shell do Visual Studio, está localizado na seguinte posição:

Localizando o Script Task dentro da SSIS Toolbox

Figura 7: Localizando o Script Task dentro da SSIS Toolbox

Após, de o nome para o mesmo de: ST_IF_Else, onde em seguida, clique com o Botão direto do Mouse sobre ele e selecione a Opção EDIT. Será aberta uma Tela, semelhante a da Figura 10, abaixo.



Editando o componente Script Task

Figura 8: Editando o componente Script Task

Conforme estão vendo na Figura 8 acima, temos a opção de selecionarmos qual linguagem estaremos trabalhando. Neste exemplo, estou utilizando a Linguagem C#, porém, poderíamos configurar a Linguagem VB .Net sem problemas, alterando nas Propriedades do Item qual Linguagem utilizaremos, conforme é apresentado na Fiura 12, abaixo.

Configurando qual Linguagem utilizar como Script

Figura 9: Configurando qual Linguagem utilizar como Script

A opção EntryPoint, descreve qual o método de Entrada que estaremos utilizando no Script. Podemos deixar em branco, ou então, descrever qual método iremos utilizar. Por padrão, eu deixei o método Main.

Após, temos duas opções que serviram tanto descrever quais as variáveis serão utilizadas para somente leitura e quais as variáveis serão utilizadas para somente escrita.

Bom, como estamos trabalhando com um Bloco de script que, deveremos interagir entre o SSIS e a tal linguagem de alguma forma. Para isso, poderemos utilizar variáveis para tanto levar um conteúdo para as rotinas do .NET, quanto trazer este retorno de processamento. Desta forma, poderemos interagir sem problemas com fluxos externos deste ambiente. Desta forma, clique com o botão direito do mouse sobre a área de desenvolvimento do Visual Studio e selecione a opção Variables.

Selecionando as opções Variables na Tela do Visual Studio

Figura 10: Selecionando as opções Variables na Tela do Visual Studio

Após, percebam que o Visual Studio abrirá uma tela, onde poderemos inserir a quantidade de variáveis que desejarmos em nosso processo. No nosso exemplo, criaremos 3 (três) variáveis, onde ainda poderemos escolher qual o Data Type estaremos utilizando e seu Valor inicial (poderemos ainda aplicar expressões para estas variáveis, mas não é o caso). Percebam também que a variável criada trabalha sobre o escopo da Package, pois como não alterei o nome do meu Pacote do Integration Services, acabou sendo adotado o nome principal do arquivo da Package.dtsx, visível na Aba Solution Explorer do Visual Studio. Perceba também que o Data Type da Variável é do tipo Object (mais para frente o mesmo será convertido para DataSet e será utilizado no Script).

Criando as variáveis que serão utilizadas no Script Task

Figura 11: Criando as variáveis que serão utilizadas no Script Task

Após criarmos a variável, teremos que selecioná-la nas Opções: ReadOnlyVariables. Neste caso não utilizaremos a opção ReadWriteVariables, pois realmente só iremos ler a variável que será encaminhada do retorno do Item o Execute T-SQL Statement. Para isso, deveremos selecioná-las na opção do Editor do Script Task, conforme apresentado na Figura 12.

Selecionando as variáveis que serão utilizadas no Script Task

Figura 12: Selecionando as variáveis que serão utilizadas no Script Task

Bom, não vou detalhar o que o Script em si está fazendo, porém, não posso deixar de explicar sua funcionalidade. Para os colegas que estão acostumados com o ambiente .NET na linguagem C# e/ou VB .NET, não sentirão dificuldades, pois, utilizaremos tais linguagens para codificar algum fluxo, onde poderia ser uma regra de negócio, ou uma chamada a uma DLL que tenha métodos de negócio encapsulados.

Perceba na Listagem 2 a descrição do Método Main, que receberá a variável ResultSet (fique a vontade para mudar este nome).

Listagem 2: Método Main do Script C#

public void Main()
{
	var dt = new DataTable();
	var oled = new OleDbDataAdapter();

	try
	{
		oled.Fill(dt, Dts.Variables["ResultSet"].Value);

		for(int i = 0; i < dt.Rows.Count; i++)
		{
			if(decimal.Parse(dt.Rows[i]["ListPrice"].ToString()) > 50 & decimal.Parse(dt.Rows[i]["ListPrice"].ToString()) < 75)
			{
				GeraArquivo_Preco50_75(int.Parse(dt.Rows[i]["ProductID"].ToString()), decimal.Parse(dt.Rows[i]["ListPrice"].ToString()), dt.Rows[i]["Name"].ToString());
			}
			else if(decimal.Parse(dt.Rows[i]["ListPrice"].ToString()) > 75 & decimal.Parse(dt.Rows[i]["ListPrice"].ToString()) < 100)
			{
				GeraArquivo_Preco75_100(int.Parse(dt.Rows[i]["ProductID"].ToString()), decimal.Parse(dt.Rows[i]["ListPrice"].ToString()), dt.Rows[i]["Name"].ToString());			
			}
			Dts.TaskResult = (int)ScriptResults.Success;
		}
	}
	catch(Exception ex)
	{
		MessageBox.Show("Erro: " + ex.Message);
		Dts.TaskResult = (int)ScriptResults.Failure;
	}
}

Este método irá pegar a variável ResultSet e a converter para um DataTable. Logo após, iremos varrer este DataTable em um FOR LOOP e para cada linha, verificaremos os campos ProductID, Name e ListPrice. Se o campo ListPrice for maior que 50 e menor que 75, chamaremos o método GeraArquivo_Preco50_75, que simplesmente irá criar um arquivo chamado Arq50_75.txt no Diretório C:\, se utilizando do Namespace System.IO.StreamWriter, inserindo via WriteLine os campos ProductID, ListaPreco, NomeProduto (traduzi o nome dos campos), concatenados por ponto e vírgula (“;”).

Listagem 3: Método que Gera o arquivo com os dados do Produto, Nome do Produto e Preço entre 50 e 75

public bool GeraArquivo_Preco50_75(int ID_Produto, decimal ListaPreco, string NomeProduto)
{
	var ret = false;
	var arq50_75 = new StreamWriter(@"C:\Arq50_75.txt", true);

	try
	{
		arq50_75.WriteLine(ID_Produto + ";" + NomeProduto + ";" + ListaPreco);
		arq50_75.Close();
	}
	catch(Exception ex)
	{
		throw new ArgumentException(ex.Message);
	}
	return ret;
}

Da mesma forma, caso o campo ListPrice for maior que 75 e menor que 100, chamaremos o Método GeraArquivoPreco75_100, que da mesma forma receberá os campos ProductID, Name e ListPrice e gerará um arquivo chamado Arq75_100.txt no C:\.

Listagem 4: Método que Gera o arquivo com os dados do Produto, Nome do Produto e Preço entre 75 e 100

public bool GeraArquivo_Preco50_75(int ID_Produto, decimal ListaPreco, string NomeProduto)
{
	var ret = false;
	var arq50_75 = new StreamWriter(@"C:\Arq75_100.txt", true);

	try
	{
		arq50_75.WriteLine(ID_Produto + ";" + NomeProduto + ";" + ListaPreco);
		arq50_75.Close();
	}
	catch(Exception ex)
	{
		throw new ArgumentException(ex.Message);
	}
	return ret;
}

Na Figura 13 abaixo, veremos os dois arquivos (na mesma janela), com seus respectivos registros, sendo que para o arquivo com Preços entre 50 e 75 é maior do que o arquivo de Preços entre 50 e 75.

Mostrando os arquivos e seus respetivos conteúdos

Figura 13: Mostrando os arquivos e seus respetivos conteúdos

Bom, vale lembrar que você poderá mudar o caminho do arquivo, ou até mesmo o nome do próprio arquivo, ou até quem sabe, programar outro Código em C# ou .NET, pois a intensão do artigo foi somente indicar a possibilidade de integrar o SSIS com as linguagens C# e VB .NET, utilizando para isso o Visual Studio 2010.

Bom estudo.