Udocs.me

Aplicativos patrocinadores


Autor: Mauricio Junior
Publicado em: 12/9/2014 5:27:47 PM

SELECT dentro de SELECT e XML

Prezado(a) Leitor(a), hoje eu vou falar um pouco sobre a maneira de fazer SELECT em duas tabelas no banco de dados. Não é um select simples até porque a linha da empresa está se repetindo sem a necessidade.

O exemplo que tenho para mostrar pra você é comum e muita gente não sabe fazer ou resolver. Vamos para o exemplo na prática: Você tem uma tabela de empresa contendo o cadastro principal e a empresa pode ter mais de um telefone, nesse caso pode ter 2 ou 20 telefones. Mesmo utilizando LEFT JOIN ou INNER JOIN as linhas vão se repetir com o mesmo nome da empresa para cada telefone. Veja a tabela 1.1.

Tabela 1.1 - Resultado das pesquisas

A tabela 1.1 mostra o resultado de um SELECT com INNER JOIN ou LEFT JOIN do banco de dados ou dentro do C#. A empresa Advogados S.A. possui dois telefones e a empresa Monitores LTDA três. A linha acabou se repetindo devido a quantidade de telefones cadastrados para a mesma empresa.

Se houver três ou quatro telefones em cada empresa, o resultado da mesma empresa vai aparece entre três ou quatro linhas com o mesmo conteúdo baseado nos telefones diferentes.

O meu problema é encontrar uma maneira de colocar todos os telefones em uma mesma coluna para não repetir a empresa. Cada linha tem que aparecer em uma linha diferente, mesmo que tenha mais de 10 telefones.

Para resolver o problema, tive que pedir ajuda a um amigo e ele me sugeriu dois caminhos. O que ele usa é o SELECT que faz seleção em XML e agrupa em uma coluna. E por incrível que pareça, funcionou no meu caso.

Como o meu projeto está dividido em camadas, criei um método na classe DAO responsável por buscar a empresa pelo nome e retorna a empresa em cada linha com vários telefones possíveis cadastrados. Vamos ver o código 1.1.

internal DataTable searchEmpresa(EmpresaDTO dto)

        {

            StringBuilder str = new StringBuilder();

            str.Append(@"SELECT e.IdEmpresa, e.NomeFantasia, e.Email, 

substring (

                                (

                                    Select   ' '+ t.DDD + '-' + t.Telefone AS [text()]

                                    From     Telefone t

                                    Where    e.IdEmpresa = t.IdEmpresa

                                    ORDER    BY t.IdEmpresa

                                    For      XML PATH ('')

                                )

                            , 2, 1000) Telefone

                        FROM     Empresa e WHERE e.NomeFantasia like @nomeFantasia ) ");


            str.Append(@" ORDER BY e.NomeFantasia, e.Logradouro ");


            SqlCommand dbCommand = new SqlCommand(str.ToString());

            dbCommand.CommandType = CommandType.Text;



            if (!String.IsNullOrEmpty(dto.nomeFantasia))

            {

                IDataParameter nomeFantasia = new SqlParameter();

                nomeFantasia.ParameterName = "@nomeFantasia";

                nomeFantasia.Value = "%" + dto.nomeFantasia + "%";

                nomeFantasia.DbType = System.Data.DbType.String;               

  dbCommand.Parameters.Add(nomeFantasia);

            }



            database.GetSourceConnection();

            return database.ExecutaDataSetParameter(dbCommand).Tables[0];

        }



Código 1.1 - Fazendo SELECT

Note que o código 1.1 começa com o SELECT mostrando os dados da empresa e depois faz um subscript com os dados do telefone. Na verdade são dois SELECTs, um dentro do outro relacionando as chaves. O segundo SELECT retorna um XML que integra no primeiro como uma coluna.

O parâmetro precisa ser passado e pra isso eu usei o IDataParamter com o nome, valor e tipo do dado passado. No final eu chamo o meu framework que envia os comandos para o banco de dados.

O resultado é simples e da maneira que eu preciso. Veja a tabela 1.2.

Tabela 1.2 - Resultado final.

Note que na tabela 1.2, os dados foram agrupados e separados com um traço dentro do SELECT. Note que o método escrito no código 1.1 retorna um DataTable que pode preencher o objeto do tipo GridView na página para o usuário.

Bom, espero que tenha gostado do que viu aqui e qualquer dúvida pode entrar em contato pelo site www.mauriciojunior.org



Udocs.me