Curso de ADO.NET e BDP - Parte VII

Acesso a dados no Delphi 8 for .NET

 

Parte VII – MetaData

Neste artigo veremos como utilizar o BDP para recuperar informações sobre os Metadados de um banco de dados, usando basicamente o método GetMetaData de BdpConnection . Você pode utilizar esse recurso para obter dados sobre os “objetos” de um banco, como nome de tabelas, colunas, tipos, tamanhos, índices, views, triggers, procedures etc.

Cada banco de dados possui um catálogo, um conjunto de tabelas que armazenam informações sobre o próprio banco de dados. Por exemplo, o DB2 guarda informações sobre TABELAS e COLUNAS em tabelas chamadas SYSTABLES e SYSCOLUMNS. O SQL Server chama de sysobjetcs e syscolumns. O Oracle armazena essas informações em tabelas como USER_TABLES e USER_COLUMNS. O InterBase / Firebird armazena informações em várias tabelas de sistema, iniciando com o prefixo “RDB$”. Para se obter informações sobre Metadados, basta que você dê um Select na respectiva tabela, de acordo com o banco usado.

O problema é que a mesma instrução não se aplica a outro BD, pois conforme vimos, as tabelas de catálogo possuem nomes e estruturas completamente diferentes.

Sabendo isso, a Borland quando criou o BDP definiu uma interface (chamada ISQLMetaData ) para padronizar a obtenção dessas informações, não importa o banco de dados que esteja utilizando. Ou seja, há um padrão, e você não precisará escrever diferentes instruções SQL para obter informações desse tipo quando precisar acessar mais de um tipo de BD.

Dessa forma, cada driver do BDP (para DB2, Oracle, IB) deve implementar essa interface para indicar como os metadados de um BD podem ser obtidos, e isso fica transparente ao programador.

A própria IDE do Delphi 8 utiliza os serviços de metadados oferecidos pelo BDP para exibir na janela Data Explorer informações sobre objetos de um banco de dados. Veja:

 

 

Como você pode ver, o Data Explorer exibe em um TreeView informações sobre tabelas, campos, StoredProcedures (e parâmetros), views etc.

O que faremos agora é uma aplicação semelhante ao Data Explorer da IDE (BDS), que permitirá ao usuário explorar os objetos do banco de dados Employee dos demos do Interbase.

Configurando os controles do formulário

Inicie uma nova aplicação Windows Forms no Delphi 8. Coloque no formulário um TreeView e dois DataGrids . Caso queria utilize Panels para servir de container para os DataGrids, de forma que fiquem sempre a direita do formulário. A propriedade Dock pode ser usada para alinhá-los.

Coloque também os seguintes componentes: ImageList , BdpCommand , BdpConnection, BdpDataAdapter e DataSet .

Abra o editor da propriedade Images do ImageList e adicione seis imagens, clicando botão Add:

 

 

Aponte a propriedade ImageListi do TreeView para ImageList1 . Abra o editor da propriedade Nodes do TreeView e adicione alguns nodes na árvore, como mostrado a seguir:

 

 

Utilize a opção Image para definir uma imagem para cada item.

Configurando o acesso a dados

A partir do Data Explorer da IDE arraste para o formulário a conexão Employee , para criar um BdpConnection . Coloque um BdpDataAdapter e aponte sua propriedade SelectCommand.Connection para BdpConnection1 . Coloque um BdpCommand e aponte sua propriedade Connection para BdpConnection1 . Coloque um DataSet e aponte a propriedade DataSet do BdpDataAdapter para esse componente. Seu formulário deve estar semelhante ao mostrado a seguir:

 

 

Nota: o componente DataSet é discutido em detalhes mais adiante, ainda neste curso. Por enquanto, basta saber que ele é responsável pela cache dados local de dados na aplicação cliente.

Respondendo aos eventos

No evento AfterSelect do TreeView digite o seguinte:

 

procedure TWinForm.TreeView1_AfterSelect(sender: System.Object; e: System.Windows.Forms.TreeViewEventArgs);

var

 dt: DataTable;

begin

 case e.Node.ImageIndex of

  1 : dt := BdpConnection1.GetMetaData.GetTables('',TableType.Table);

  2 : dt := BdpConnection1.GetMetaData.GetTables('',TableType.View);

  3 : dt := BdpConnection1.GetMetaData.GetProcedures

              ('',ProcedureType.Procedure);

 end;

 { Selecionou um a Tabela }

 if e.Node.ImageIndex = 4 then

 begin

  { pega MetaData }

  dt := BdpConnection1.GetMetaData.GetColumns

  (e.Node.Text,'',ColumnType.Unknown);

  DataGrid1.DataSource := dt;

  { pega dados }

  BdpCommand1.CommandType := CommandType.TableDirect;

  BdpCommand1.CommandText := e.Node.Text;

  BdpDataAdapter1.Active := False;

  BdpDataAdapter1.Active := True;

  DataGrid2.DataSource := DataSet1.Tables[0];

  DataGrid2.CaptionText := e.Node.Text + ' (Dados)';

 end;

 DataGrid2.Visible := e.Node.ImageIndex = 4;

 if dt <> nil then

 begin

  DataGrid1.DataSource := dt;

  DataGrid1.CaptionText := e.Node.Text + ' (MetaDados)';

 end ;

end ;

 

O código anterior verifica o tipo de nó selecionado (tabela, view ou StoredProcedure ), e chama o método GetMetaData do BdpConnection para extrair os metadados do banco conforme a seleção do usuário.

GetMetaData possui vários métodos, por exemplo, GetTables retorna os nomes das tabela do banco, enquanto GetProcedures retorna os nomes dos StoredProcedures .GetColumns pode ser usado para obter as colunas (com nome, tamanho, tipo etc.) de uma tabela do BD. O resultado da chamada desses métodos é um DataTable , componente interno ao DataSet , que armazena uma estrutura de dados na aplicação cliente representando uma tabela do banco. Ou seja, você pode utilizar o próprio DataGrid para exibir os dados retornados pela chamada a esses métodos, como fizemos no código anterior.

Declare na seção strict private da classe do formulário um método chamado ConfiguraTreeView , e implemente-o da seguinte forma:

 

procedure TWinForm.ConfiguraTreeView;

var

 dt1, dt2: DataTable;

 i,j,t: integer;

 n1,n2: TreeNode;

 s1,s2: string ;

 pNode: TreeNode;

 row: DataRow;

begin

 { Preenche Tabelas e Views }

 for t := 1 to 2 do

 begin

   if t = 1 then // tabela

   begin

    pNode := TreeView1.Nodes[0].Nodes[0];

    dt1 := BdpConnection1.GetMetaData.GetTables('',TableType.Table);

   end

   else // views

   begin

    pNode := TreeView1.Nodes[0].Nodes[1];

    dt1 := BdpConnection1.GetMetaData.GetTables('',TableType.View);

   end ;

   for i := 0 to pred(dt1.Rows.Count) do

   begin

   row := dt1.Rows[i];

   s1 := row['TableName'].ToString;

   n1 := TreeNode.Create(s1);

   n1.ImageIndex := 4;

   n1.SelectedImageIndex := 4;

   pNode.Nodes.Add(n1);

   { Preenche Campos para cada Tabela }

   dt2 := BdpConnection1.GetMetaData.GetColumns(s1,'',ColumnType.Unknown);

    for j := 0 to pred(dt2.Rows.Count) do

    begin

     row := dt2.Rows[j];

     s2 := row['ColumnName'].ToString;

     n2 := TreeNode.Create(s2);

     n2.ImageIndex := 5;

     n2.SelectedImageIndex := 5;

     n1.Nodes.Add(n2);

    end;

 end;

end;

{ Preenche Procedures }

pNode := TreeView1.Nodes[0].Nodes[2];

dt1 := BdpConnection1.GetMetaData.GetProcedures('',ProcedureType.Procedure);

for i := 0 to pred(dt1.Rows.Count) do

begin

  row := dt1.Rows[i];

  s1 := row['ProcName'].ToString;

  n1 := TreeNode.Create(s1);

  n1.ImageIndex := 3;

  n1.SelectedImageIndex := 3;

  pNode.Nodes.Add(n1);

  dt2 := BdpConnection1.GetMetaData.GetProcedureParams(s1,'');

   for j := 0 to pred(dt2.Rows.Count) do

   begin

    row := dt2.Rows[j];

    s2 := row['ParamName'].ToString;

    n2 := TreeNode.Create(s2);

    n2.ImageIndex := 5;

    n2.SelectedImageIndex := 5;

    n1.Nodes.Add(n2);

   end;

 end;

end;

 

O código anterior monta a estrutura do TreeView no lado esquerdo do formulário, inicializando os valores dos nós, para exibir os nomes das tabelas, StoredProcedures e views disponíveis no BD.

No evento Load do formulário chamamos esse método e abrimos a conexão:

 

procedure TWinForm.TWinForm_Load

  (sender: System.Object; e: System.EventArgs);

begin

  BdpConnection1.Open;

  ConfiguraTreeView;

  TreeView1.CollapseAll;

end;

Testando o “Data Explorer”

Execute a aplicação. Observe que o TreeView exibe agora os objetos do BD. Expandindo uma tabela por exemplo, você tem acesso aos seus campos. Se expandir um StoredProcedure , você pode ver seus parâmetros:

 

 

Clicando sobre uma tabela, os dois DataGrids são configurados. O primeiro mostra os metadados recuperados para tabela, como nomes dos campos, tipos, tamanhos etc. O segundo mostra os dados da tabela:

 

 

O mesmo acontece para Views. E finalmente, se você clicar sobre um StoredProcedure , verá os metadados desse objeto:

 

 

Download

Você pode fazer download de todos os exemplos deste curso de acesso a dados no Delphi 8 com ADO.NET e BDP a partir do endereço http://cc.borland.com/cc/ccweb.exe/author?authorid=222668

Na próxima parte do curso conheceremos o segundo grupo de componentes do ADO.NET, os componentes “desconectados”, como o DataSet e DataTable . Um abraço e até lá!

Leia todos artigos da série