Arquivo de maio, 2014

Websites – Iteradores – Javascript

Publicado: 18 de maio de 2014 em JavaScript

Em português iterador, é um objeto que permite a um programador examinar uma coleção ou container. Vários tipos de iteradores são frequentemente fornecidos através de uma interface de container. Apesar da interface e semântica de um determinado iterador serem fixas, iteradores são frequentemente implementados em termos de estruturas subjacentes a uma implementação de container e são muitas vezes ligados intimamente ao container para permitir a semântica operacional do iterador.

Observe que um iterador percorre e também dá acesso aos elementos de dados em um container, mas não realiza iteração (isto é, não sem alguma liberdade significativa tomada com este conceito ou com uso trivial da terminologia). Um iterador tem um comportamento semelhante a um cursor de banco de dados. Iteradores datam da linguagem de programação CLU de 1974.

Iteradores - Javascript

Iteradores – Javascript

Exemplo:

Neste exemplo escrevemos iteradores que navegam por um objeto javascript e iteram suas propriedades e os conteúdos de cada propriedade, também uma função que itera valores usando a clássica instrução next.

Html / JavaScript

<!DOCTYPE html>
<html>
 
<head>
   <title>Desenvolvimento Aberto</title>
</head>
 
<body>
 
<h2>Desenvolvimento Aberto</h2>
<h3>Javascript Orientado a Objeto - Iteradores</h3>
<h4>JavaScript</h4>
<br>

<pre>
<script>
 
 
document.writeln("Iteradores: navega pelas propriedades\n");

// Cria propriedades 
var propriedade;
var conteudo ="";

// Cria objeto
var objeto = { propriedade1:1, propriedade2:2, propriedade3:3 }; 

// Itera propriedades
for (propriedade in objeto) document.writeln(propriedade);

// itera objetos
document.writeln("\nIteradores: navega pelos valores das propriedades\n");
for (var i in objeto)
   {
      conteudo = objeto[i]
      document.writeln(conteudo);
   }

document.writeln("\nIteradores: proximo e anterior");

// Função cria iterador next
function contador(valor)
{
   var iterador = valor;
   return { next: function() { return iterador = iterador + 1; }}  
}

// verifica iterador
var numeros = contador(10);
document.writeln("\nIteradores: numero = 10");
document.writeln("Iteradores: proximo = " + numeros.next());

</script>
</pre>
 
</body>
 
</html>

Não existe um método simples para mostrar e manipular dados em uma grade na linguagem de programação Python, o método mais simples é bem parecido com o método utilizado em C++, você precisa escrever um código que retorna arrays e vetores para preencher a grade como se fosse uma tabela e precisa escrever métodos que permitem manipular a grade de vários modos, você encontra a toda documentação necessária neste link:

Classe WxGrid: http://wiki.wxpython.org/wxGrid#The_wxGrid_Class

WxGrid - Oracle

WxGrid – Oracle

Oracle

Você pode retornar os dados de uma tabela do banco de dados Oracle criando um cursor e executando uma pesquisa sobre ele, você utiliza o método fetchall() para retornar todas as linhas do seu set de dados.

Exemplo:

Neste exemplo criamos uma grade de dados e a preenchemos com os dados retornados de uma pesquisa no banco de dados.

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# GradeDados.py

# importa modulos
import wx
import wx.grid
import cx_Oracle

# Cria classe generica de uma WX.Grid
# A classe abaixo faz parte da documentação WXPython oficial
# Este trecho de código é util para manipular a grade

class GenericTable(wx.grid.PyGridTableBase):
    def __init__(self, data, rowLabels=None, colLabels=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.rowLabels = rowLabels
        self.colLabels = colLabels

    def GetNumberRows(self):
        return len(self.data)

    def GetNumberCols(self):
        return len(self.data[0])

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]

    def GetRowLabelValue(self, row):
        if self.rowLabels:
            return self.rowLabels[row]

    def IsEmptyCell(self, row, col):
        return False

    def GetValue(self, row, col):
        return self.data[row][col]

    def SetValue(self, row, col, value):
        pass       

# Cria conexão Oracle
def conectarORA():
    sconexao = "user/p@55w0rd@localhost/XE"
    try:
        con = cx_Oracle.connect(sconexao)
    except ValueError:
        tkMessageBox.showinfo(title="Menssagem", message="Erro de Conexão", parent=janela)
    return con

# Cria conexão
con = conectarORA()

# Executa e retorna SQL
def retornaTabelaORA(sql, con):
    cursor = con.cursor()
    cursor.execute(sql)
    return cursor

# Inicializa Grade
dados = []
colLabels  = []
rowLabels = ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10")   

#Retorna metadados
colunas = retornaTabelaORA("select COLUMN_NAME from ALL_TAB_COLUMNS where TABLE_NAME='BLOG'", con)
metadados = colunas.fetchall()
for cols in metadados:
    colLabels.append(str(str(str(str(cols).replace("(","")).replace(")","")).replace(",","")).replace("'",""))

# Envia dados a grid
tabela = retornaTabelaORA("Select * from Blog", con)
resultado = tabela.fetchall()
for conteudo in resultado:
    dados.append(conteudo)

# Cria classe da grid
class SimpleGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1, pos=(5,60), size=(850,200))
        tableBase = GenericTable(dados, rowLabels, colLabels)
        self.SetTable(tableBase)                   

# Cria formulario
class TestFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "Acessando Dados Oracle DataBase", size=(900, 350))
        panel = wx.Panel(self, wx.ID_ANY)
        label=wx.StaticText(panel, -1, label='WXPython - DataGrid - Oracle Database XE', pos=(300,20))
        grid = SimpleGrid(panel)

# Inicializa a aplicação
app = wx.PySimpleApp()
frame = TestFrame(None)
frame.Show(True)
app.MainLoop()

Na linguagem C++ utilizando MFC, você pode manipular dados de qualquer banco de dados que possua um driver suportado pelo ODBC, um sistema de grande porte geralmente utiliza mais de um banco de dados, esta opção torna seu produto mais competitivo no mercado pois pode suportar varias especificações técnicas de hardware e software, assim obtendo vantagem no preço final de sua implementação.

CRecordSet

Representa um conjunto de registros selecionados a partir de uma fonte de dados. Esta classe permite que você manipule por completo um set de dados, obtendo além dos dados contidos na tabela, também seus metadados e contadores uteis para manipular o resultado de uma query em tempo de execução.

Conectando ao Oracle, IBM DB2 e Microsoft SQL Server a partir da mesma Aplicação:

Para efetuar as conexões com os diferentes bancos de dados você precisa primeiro configurar os drivers ODBC necessários no sistema operacional, depois você pode criar um design com 3 componentes RadioButton, um componente Button e um componente CListControl,  você encontra um walkthrough de como configurar os drivers ODBC na categoria SQL e C++ deste site, use a figura abaixo para referencia do design:

Design

Design

Retornando dados do Oracle:

Oracle

Oracle

Retornando dados do IBM DB2:

IBM DB2

IBM DB2

Retornando dados do Microsoft SQL Server:

MSSQL

MSSQL

Exemplo:

Neste exemplo criamos uma aplicação MFC Dialog Based e utilizamos uma única conexão para retornar um set de dados comum para cada banco de dados utilizados no programa.  Use os trechos do código abaixo para completar seu código gerado automaticamente.

C++

Arquivo .h

// Classe gerada automaticamente
// AcessocppDlg.h : header file
//

#pragma once

// Inclui classe de banco de dados MFC
#include "afxdb.h"
#include "afxcmn.h"

class CAcessocppDlg : public CDialogEx
{

public:
	CAcessocppDlg(CWnd* pParent = NULL);	// standard constructor

	enum { IDD = IDD_ACESSOCPP_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support

protected:
	HICON m_hIcon;

	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:

	// Cria métodos e objetos da classe
	CDatabase db;
	CString bancodedados;
	void conectarDB(CString dns, CString usuario, CString senha);

	afx_msg void OnBnHotItemChangeRadio1(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnBnHotItemChangeRadio2(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnBnHotItemChangeRadio3(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnBnClickedButton1();
	CListCtrl m_tabela;
};

Arquivo .cpp

// Código gerado automaticamente
// AcessocppDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Acessocpp.h"
#include "AcessocppDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);   

protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()

CAcessocppDlg::CAcessocppDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CAcessocppDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CAcessocppDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST2, m_tabela);
}

BEGIN_MESSAGE_MAP(CAcessocppDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_NOTIFY(BCN_HOTITEMCHANGE, IDC_RADIO1, &CAcessocppDlg::OnBnHotItemChangeRadio1)
	ON_NOTIFY(BCN_HOTITEMCHANGE, IDC_RADIO2, &CAcessocppDlg::OnBnHotItemChangeRadio2)
	ON_NOTIFY(BCN_HOTITEMCHANGE, IDC_RADIO3, &CAcessocppDlg::OnBnHotItemChangeRadio3)
	ON_BN_CLICKED(IDC_BUTTON1, &CAcessocppDlg::OnBnClickedButton1)
END_MESSAGE_MAP()

BOOL CAcessocppDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	SetIcon(m_hIcon, TRUE);
	SetIcon(m_hIcon, FALSE);		

	// Desenvolvimento Aberto
	// Inicializa dialogo

	// Define variavel padrão para o banco de dados
	bancodedados = "oracle";

	// Cria o modelo de exibição de dados
	m_tabela.SetView(LV_VIEW_DETAILS);
	m_tabela.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES);

	return TRUE;
}

void CAcessocppDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

void CAcessocppDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); 

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

HCURSOR CAcessocppDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

// **************************
// * Desenvolvimento Aberto *
// **************************
// Nosso código começa aqui

// Seleciona banco de dados Oracle
void CAcessocppDlg::OnBnHotItemChangeRadio1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMBCHOTITEM pHotItem = reinterpret_cast<LPNMBCHOTITEM>(pNMHDR);

	bancodedados = "oracle";
	*pResult = 0;
}

// Seleciona banco de dados IBM DB2
void CAcessocppDlg::OnBnHotItemChangeRadio2(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMBCHOTITEM pHotItem = reinterpret_cast<LPNMBCHOTITEM>(pNMHDR);

	bancodedados = "db2";
	*pResult = 0;
}

// Seleciona banco de dados MSSQL
void CAcessocppDlg::OnBnHotItemChangeRadio3(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMBCHOTITEM pHotItem = reinterpret_cast<LPNMBCHOTITEM>(pNMHDR);

	bancodedados = "mssql";
	*pResult = 0;
}

// Evento de clique do botão
void CAcessocppDlg::OnBnClickedButton1()
{
	// campo de dado da tabela
	CString m_campo;

	// Abre conexão
	if (bancodedados == "oracle")
	{
		conectarDB(L"OracleXE", L"daberto", L"p@55w0rd");
	}

	if (bancodedados == "db2")
	{
		conectarDB(L"IBMDB2", L"db2admin", L"p@55w0rd");
	}

	if (bancodedados == "mssql")
	{
		conectarDB(L"MSSQLSERVER", L"devaberto", L"p@55w0rd");
	}

	// Cria um set de dados
	CRecordset  dados(&db);

	// Executa instrução SQL
	if (bancodedados == "db2")
	{
		dados.Open(CRecordset::forwardOnly, L"Select * From DA.\"Blog\"");
	}
	else
	{
		dados.Open(CRecordset::forwardOnly, L"Select * From Blog");
	}

	// Cria item
	LVITEM lvItem;

	// cria estrutura para inserir o item
	typedef struct _LVITEM
	{
		UINT mask;
		int iItem;
		int iSubItem;
		UINT state;
		UINT stateMask;
		LPTSTR pszText;
		int cchTextMax;
		int iImage;
		LPARAM lParam;
        #if (_WIN32_IE >= 0x0300)
		  int iIndent;
        #endif
	 } LVITEM, FAR *LPLVITEM;

	// Define variaveis de itens
	int InsertItem(const LVITEM* pItem);
	int nItem;

	// Converte CString para LPTSTR atraves de um TCHAR
	TCHAR sz[1024];

	// Verifica colunas
	short nFields = dados.GetODBCFieldCount();
	int colunas = m_tabela.GetHeaderCtrl()->GetItemCount();

	// Verifica colunas
	if (colunas == 0)
	{
		// Lê metadata da tabela
		CODBCFieldInfo field;
		for (UINT i = 0; i < nFields; i ++)
		{
			dados.GetODBCFieldInfo(i, field);
			m_tabela.InsertColumn(i, field.m_strName, LVCFMT_LEFT, 100);
		}

	}

	// Deleta itens do controle de lista
	m_tabela.DeleteAllItems();

	// Recupera dados da tabela
	while (!dados.IsEOF())
	{
		for (short index = 0; index < nFields; index++)
		{
			dados.GetFieldValue(index, m_campo);

			// Retorna linha do banco de dados
			if (index == 0)
			{
				// Insere linha
				lvItem.mask = LVIF_TEXT;
				lvItem.iItem = 0;
				lvItem.iSubItem = 0;
				lvItem.pszText = lstrcpy(sz, m_campo);
				nItem = m_tabela.InsertItem(&lvItem);
			}

			// Retorna colunas da linha
			m_tabela.SetItemText(nItem, index, lstrcpy(sz, m_campo));

		}
		// Move o cursor para a proxima linha
		dados.MoveNext();
	}

	// Fecha o set de dados e a conexão
	dados.Close();
	db.Close();

}

void CAcessocppDlg::conectarDB(CString dns, CString usuario, CString senha)
{
	// Cria string de conexão ODBC
	CString conexao;

	// Cria string de conexão
	conexao = L"DSN=" + dns + L";UID=" + usuario + L";PWD=" + senha;

	// Abre conexão
	db.OpenEx(conexao, 0);
}

Com a linguagem de programação C# você pode escrever um software que será apto a se conectar a qualquer banco de dados que possua um driver ADO.NET, por exemplo você pode se conectar ao Microsoft SQL Server usando o namespace System.data.SqlClient, e também pode se conectar ao Oracle usando o namespace System.Data.OracleClient, desde que você faça uma referencia em projeto ao assembler System.Data.OracleClient.dll.

Você pode ver mais exemplos de conexões ADO.NET:

http://msdn.microsoft.com/pt-br/library/dw70f090(v=vs.110).aspx

Porem os drivers ADO.NET fazem parte do componente de dados do Windows chamado MDAC e não podem acessar todos os recursos dos bancos de dados Oracle e IBM DB2, então se o seu software pretende usar recursos avançados de segurança entre outros e se seu servidor estiver em uma plataforma não Microsoft é recomendado que você utilize os métodos nativos de conexão para cada um dos banco de dados que você utilizar. Por exemplo, para Oracle você pode usar o ODAC 12c, e para IBM DB2 você pode usar o IBM Data Server Provider for .NET, você encontra um walkthrough de como instalar e utilizar os dois componentes aqui neste site na categoria SQL e C#.

DataGridView

Exibe dados em uma grade personalizável.

DataTable

Representa uma tabela de dados na memória.

Conectando ao Oracle, IBM DB2 e Microsoft SQL Server a partir da mesma Aplicação:

Para efetuar as conexões com os diferentes bancos de dados você precisa primeiro configurar seu projeto com os assemblers ADO.NET  necessários e depois você pode criar um design com 3 componentes RadioButton, um componente Button e um componente DataGridView use a figura abaixo para referencia:

ADO.NET Assemblers

ADO.NET Assemblers

Retornando dados do Oracle:

Oracle

Oracle

Retornando dados do IBM DB2:

IBM DB2

IBM DB2

Retornando dados do Microsoft SQL Server:

MSSQL Server

MSSQL Server

Exemplo:

Neste exemplo criamos três tipos de conexões diferentes, uma para cada banco de dados e utilizamos um set de dados comum para retornar dados dos três banco de dados utilizados no programa.

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using Oracle.DataAccess.Client;
using IBM.Data.DB2; 

namespace Acesso
{
    public partial class Dados : Form
    {
        private static OracleConnection connORA; // ODAC 12c
        private static DB2Connection connDB2;   // IBM Data Server Provider
        private static SqlConnection connMSSQL; // ADO .NET

        DataTable dataTable;

        string sql;
        static string bancodedados;

        public Dados()
        {
            InitializeComponent();
        }

        // Cria métodos de conexão
        public void conexaoODAC(string Username, string Password, string Datasource)
        {
            try
            {
                // String de Conexao
                string connectionString =

                    // Usuario
                    "User Id=" + Username +

                    // Senha
                    ";Password=" + Password +

                    // TNSnames
                    ";Data Source=" + Datasource;

                //Conecta ao datasource usando a conexão Oracle
                 connORA = new OracleConnection(connectionString);

                //Abre a conexão com o banco de dados
                connORA.Open();

            }
            // Retorna erro
            catch (Exception ex)
            {
                // Mostra menssagem de erro
                MessageBox.Show(ex.ToString());

            }
        }

        void conexaoDB2(string Server, string Database,
                                    string Username, string Password, string Timeout)
        {
            try
            {
                // String de Conexao
                string connectionString =

                    // Servidor
                    "Server=" + Server +

                    // Banco de dados
                    ";Database=" + Database +

                    // Usuario
                    ";UID=" + Username +

                    // Senha
                    ";PWD=" + Password +

                    // Timeout
                    ";Connect Timeout=" + Timeout;

                //Conecta ao datasource usando a conexão DB2
                connDB2 = new DB2Connection(connectionString);

                //Abre a conexão com o banco de dados
                connDB2.Open();                

            }
            // Retorna erro
            catch (Exception ex)
            {
                // Mostra menssagem de erro
                MessageBox.Show(ex.ToString());

            }
        }

         public void conexaoMSSQL(string Server, string Database,
                                     string Username, string Password, string Timeout)
         {
             try
             {
                 // String de Conexao
                 string connectionString =

                     // Servidor
                     "Data Source=" + Server +

                     // Banco de dados
                     ";Initial Catalog=" + Database +

                     // Usuario
                     ";User ID =" + Username +

                     // Senha
                     ";Password=" + Password +

                     // Timeout
                     ";Connect Timeout=" + Timeout;

                 //Conecta ao datasource usando a conexão Padrão
                 connMSSQL = new SqlConnection(connectionString);

                 //Abre a conexão com o banco de dados
                 connMSSQL.Open();

             }
             // Retorna erro
             catch (Exception ex)
             {
                 // Mostra menssagem de erro
                 MessageBox.Show(ex.ToString());

             }
         }

        // Retorna um set de dados
         public  DataTable retornaTabela(string sql)
         {
             Dados acesso = new Dados();

             if (bancodedados == "oracle")
             {
                 acesso.conexaoODAC("daberto", "p@55w0rd", "XE");

                 OracleCommand oracmd = new OracleCommand(sql, connORA);
                 OracleDataReader orareader = oracmd.ExecuteReader();
                 dataTable = new DataTable();
                 dataTable.Load(orareader);
             }

             if (bancodedados == "db2")
             {
                 acesso.conexaoDB2("localhost", "DEVA", "db2admin", "p@55w0rd", "40");

                 DB2Command db2cmd = new DB2Command(sql);
                 db2cmd.Connection = connDB2;
                 DB2DataReader db2reader = db2cmd.ExecuteReader();
                 dataTable = new DataTable();
                 dataTable.Load(db2reader);                

             }

             if (bancodedados == "mssql")
             {
                 acesso.conexaoMSSQL("localhost", "DevAberto", "devaberto", "p@55w0rd", "");

                 SqlCommand mssqlcmd = new SqlCommand(sql);
                 mssqlcmd.Connection = connMSSQL;
                 SqlDataReader mssqlreader = mssqlcmd.ExecuteReader();
                 dataTable = new DataTable();
                 dataTable.Load(mssqlreader);

             }

             return  dataTable;
         }

        // configura programa
        private void Form1_Shown(object sender, EventArgs e)
        {
            radioButton1.Checked = true;
            bancodedados = "oracle";
        }

        // Conecta dados
        private void button1_Click(object sender, EventArgs e)
        {
            Dados dados = new Dados(); 

            if (bancodedados == "db2")
            {
                dataGridView1.DataSource = dados.retornaTabela("Select * from DA.\"Blog\"");
            }
            else
            {
                dataGridView1.DataSource = dados.retornaTabela("Select * from Blog");
            }
        }

        // Seleciona banco de dados Oracle
        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton1.Checked)
            {
                bancodedados = "oracle";
            }

        }

        // Seleciona banco de dados IBM DB2
        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton2.Checked)
            {
                bancodedados = "db2";
            }
        }

        // Seleciona banco de dados MSSQL Server
        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton3.Checked)
            {
                bancodedados = "mssql";
            }
        }
    }
}

Você pode manipular dados de qualquer banco de dados que possua um driver suportado pelo JDBC, um sistema de grande porte geralmente utiliza mais de um banco de dados, esta opção torna seu produto mais competitivo no mercado pois pode suportar varias especificações técnicas de hardware e software, assim obtendo vantagem no preço final de sua implementação.

O Java Swing foi criados para suportar o modelo de programação MVC, utilizando modelos e visões combinando o controle com os eventos listner de seus componentes, que a grosso modo funciona assim:

A visão se registra como um ouvinte do modelo. Quaisquer alterações nos dados subjacentes do modelo resultará imediatamente em uma notificação de alteração de transmissão, que a visão recebe.

O programa neste post não possui a estrutura MVC, nem qualquer outro tipo de estrutura é composto propositalmente de apenas uma classe que conecta em 3 bancos de dados diferentes e utiliza um modelo default para retornar a mesma visão para qualquer uma das conexões.

Default Table Model

É uma implementação do TableModel que usa vetores para armazenar os objetos de valor de célula. Apesar deste modelo ser fácil de usar é necessário que você crie seus próprios modelos, este tipo de modelo possui varias restrições e necessita que você crie alguns métodos override para manipula-lo corretamente. Quando o DefaultTableModel for usado com um TableRowSorter resultará em um uso extensivo de toString, e para os tipos de dados não string o custo será alto demais. A Oracle avisa que os objetos serializados desta classe não será compatível com os futuros lançamentos do Swing.

Conectando ao Oracle, IBM DB2 e Microsoft SQL Server a partir da mesma Aplicação:

Para efetuar as conexão com os diferentes bancos de dados você precisa primeiro configurar seu projeto com os drivers JDBC necessários, use a figura abaixo para referencia:

Drivers JDBC

Drivers JDBC

Conectando ao Oracle:

Oracle

Oracle

Conectando ao IBM DB2:

IBM DB2

IBM DB2

Conectando ao Microsoft SQL Server:

MSSQL SERVER

MSSQL SERVER

Exemplo:

Neste exemplo criamos três conexões diferentes e retornamos dados da mesma tabela de 3 bancos de dados diferentes, utilizando o mesmo modelo e a mesma visão. Este exemplo deve ser modificado para poder ser usado em uma aplicação real. Você deve fazer varias modificação neste programa e criar as parametrizações necessárias, você também deve separar esta classe em varias outras classes e deve criar sua própria classe para o modelo de tabela ao invés de usar o DefaultTableModel. Este exemplo apesar de não poder ser usado em uma aplicação real ainda sim é um ótimo rascunho inicial.

Java

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class Acesso implements ActionListener, ItemListener {
	// Cria componentes
	private JTable tabela;
	private JRadioButton banco1;
	private JRadioButton banco2;
	private JRadioButton banco3;
	private JButton botao;

	// Declara objetos de conexão
	private static Connection conn;
	private static Statement query;
	private static String bancodedados;

	public void conectar(String login, String senha) {

		// Verifica strings de conexão

		// ORACLE
		if (bancodedados == "oracle") {
			try {
				// Define Driver de conexão JDBC thin
				Class.forName("oracle.jdbc.driver.OracleDriver");
				conn = DriverManager.getConnection(
						"jdbc:oracle:thin:@localhost:1521:xe", login, senha);

				// Executa pedido SQL
				query = conn.createStatement();

			}

			catch (ClassNotFoundException ex) {
				ex.printStackTrace();
			}

			catch (SQLException ex) {
				ex.printStackTrace();
			}
		}

		// DB2
		if (bancodedados == "db2") {
			try {
				// Define Driver de conexão JDBC
				Class.forName("com.ibm.db2.jcc.DB2Driver");
				conn = DriverManager.getConnection(
						"jdbc:derby:net://localhost:50000/deva", login, senha);

				// Executa pedido SQL
				query = conn.createStatement();
				// JOptionPane.showMessageDialog(menssagem,
				// "Conexão Efetuada com sucesso!");
			}

			catch (ClassNotFoundException ex) {
				ex.printStackTrace();
			}

			catch (SQLException ex) {
				// JOptionPane.showMessageDialog(menssagem, "Erro na conexão!");
				ex.printStackTrace();
			}

		}

		// MICROSOFT SQL SERVER
		if (bancodedados == "mssql") {
			try {
				// Define Driver de conexão JDBC
				String URL = "jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databaseName=devaberto"
						+ ";user=" + login + ";password=" + senha;

				Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
				conn = DriverManager.getConnection(URL);

				// Executa pedido SQL
				query = conn.createStatement();

			}

			catch (ClassNotFoundException ex) {
				ex.printStackTrace();
			}

			catch (SQLException ex) {
				ex.printStackTrace();
			}

		}

	}

	public ResultSet retornaTabela() throws SQLException {
		// Cria uma nova conexão
		Statement query;
		query = conn.createStatement();
		String sql;

		// Verfica banco de dados e passa script SQL
		if (bancodedados == "db2") {
			sql = "Select * from DA.\"Blog\"";
		} else {
			sql = "Select * from blog";
		}

		// Executa Script
		ResultSet dados = query.executeQuery(sql);

		// Retorna set de dados
		return dados;
	}

	// Modelo
	public static DefaultTableModel criaTableModel(ResultSet rs)
			throws SQLException {

		// Cria um modelo de tabela
		ResultSetMetaData metaData = rs.getMetaData();

		// Retorna as colunas
		Vector<String> colunas = new Vector<String>();

		int columnCount = metaData.getColumnCount();

		for (int column = 1; column <= columnCount; column++) {
			colunas.add(metaData.getColumnName(column));
		}

		// Retorna dados
		Vector<Vector<Object>> dados = new Vector<Vector<Object>>();

		while (rs.next()) {
			Vector<Object> vector = new Vector<Object>();

			for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
				vector.add(rs.getObject(columnIndex));
			}
			dados.add(vector);
		}

		return new DefaultTableModel(dados, colunas);

	}

	public void itemStateChanged(ItemEvent arg0) {

		// Verifica item banco de dados selecionado
		Object fonte = arg0.getItemSelectable();
		int estado = arg0.getStateChange();

		if (estado == arg0.SELECTED) {

			if (fonte == banco1) {
				bancodedados = "oracle";
			}

			if (fonte == banco2) {
				bancodedados = "db2";
			}

			if (fonte == banco3) {
				bancodedados = "mssql";
			}

		}

	}

	public void actionPerformed(ActionEvent arg0) {
		// Efetua login no banco de dados
		Acesso acesso = new Acesso();

		if (bancodedados == "oracle") {
			acesso.conectar("daberto", "p@55W0rd");
		}

		if (bancodedados == "db2") {
			acesso.conectar("db2admin", "p@55W0rd");
		}

		if (bancodedados == "mssql") {
			acesso.conectar("devaberto", "p@55W0rd");
		}

		try {
			tabela.setModel(criaTableModel(acesso.retornaTabela()));
		} catch (SQLException e) {
			e.printStackTrace();
		}

	}

	public Container criaPainel() throws SQLException {
		// Cria painel principal
		JPanel painel = new JPanel();

		// Seleciona layout
		painel.setLayout(new BoxLayout(painel, BoxLayout.PAGE_AXIS));
		painel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

		// Cria painel de escolha de conexão
		JPanel pescolha = new JPanel();

		pescolha.setLayout(new BoxLayout(pescolha, BoxLayout.LINE_AXIS));
		pescolha.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

		ButtonGroup grupo = new ButtonGroup();

		// Cria componentes de radio
		banco1 = new JRadioButton("Oracle");
		banco2 = new JRadioButton("IBM DB2");
		banco3 = new JRadioButton("Microsoft SQL");

		// Agrupa botões de radio
		grupo.add(banco1);
		grupo.add(banco2);
		grupo.add(banco3);

		// Cria ouvinte dos botões
		banco1.addItemListener(this);
		banco2.addItemListener(this);
		banco3.addItemListener(this);

		// Seleciona primeira conexão
		banco1.setSelected(true);

		// Adiciona botões ao painel
		pescolha.add(banco1);
		pescolha.add(banco2);
		pescolha.add(banco3);

		// Efetua primeira conexão ao banco (ORACLE)
		Acesso acesso = new Acesso();
		acesso.conectar("daberto", "p@55W0rd");

		// Cria modelo de tabela
		tabela = new JTable(criaTableModel(acesso.retornaTabela()));

		// Adiciona um painel de rolagem
		JScrollPane rolar = new JScrollPane(tabela);

		// Cria painel do botão
		JPanel pbotao = new JPanel();

		// Seleciona layout
		pbotao.setLayout(new BoxLayout(pbotao, BoxLayout.PAGE_AXIS));

		// cria botão
		botao = new JButton("Ler dados");
		botao.addActionListener(this);

		// Adiciona botão ao painel
		pbotao.add(botao);

		// componentes ao painel principal
		painel.add(pescolha);
		painel.add(rolar);
		painel.add(Box.createVerticalStrut(10));
		painel.add(botao);

		return painel;
	}

	public static void criaGUI() {
		// Cria formulario
		JFrame formulario = new JFrame("Acessando Dados");
		formulario.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// cria painel de conteudo
		Acesso acesso = new Acesso();

		try {
			formulario.setContentPane(acesso.criaPainel());
		}

		catch (SQLException e) {
			e.printStackTrace();
		}

		// Exibe o formulario
		formulario.pack();
		formulario.setVisible(true);
	}

	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {

				// Cria e mostra a GUI
				criaGUI();

			}
		});
	}
}

A grande maioria das empresas necessitam de sistemas que possam processar, guardar e manipular informações e o modo mais comum de se fazer este trabalho é usando um banco de dados relacional. Um sistema de gerenciamento de banco de dados relacional (RDBMS) é um sistema de gerenciamento de banco de dados (SGBD), que é baseado no modelo relacional introduzido por EF Codd, do Laboratório de Pesquisa de San Jose da IBM. Muitos bancos de dados populares atualmente em uso são baseados no modelo de banco de dados relacional.

Os RDBMSs tornaram-se uma escolha predominante para o armazenamento de informações em bancos de dados, usados para registros financeiros, fabricação e informações logísticas, dados de pessoal, e muito mais desde 1980. Bancos de dados relacionais, muitas vezes substituindo bancos de dados hierárquicos e bancos de dados de rede, porque eles são mais fáceis de entender e usar. No entanto, os bancos de dados relacionais vem sendo substituídos por banco de dados orientados a objeto que foram introduzidos na tentativa de resolver a diferença de impedância objeto-relacional em banco de dados relacional e bancos de dados XML.

Banco de Dados Relacional

Banco de Dados Relacional

Entre os maiores banco de dados relacionais do mercado, segundo a empresa Gartner, os líderes de vendas são:

  1. Oracle (48.8%),
  2. IBM (20.2%),
  3. Microsoft (17.0%),
  4. SAP incluindo (Sybase (4.6%), e Teradata (3.7%))

Banco de dados o grande vilão

Quem já ouviu esta afirmação? “O sistema está muito lento!”. Existem vários fatores que podem causar este problema mas eu já ouvi o que considero a pior resposta do mundo de para esta afirmação e foi de um especialista da empresa líder nacional do mercado para ERP, da qual você já imaginou o nome. O sistema estava em um cliente multinacional que fabrica peças para montadoras de carros e rodava sobre o banco de dados Microsoft SQL Server, e o consultor da tal empresa  disse: “Troca o banco de dados pelo Oracle“. Instantaneamente o gerente de TI  replicou: “Neste caso é melhor eu trocar seu sistema pelo SAP!”.

Eu concordo plenamente com a resposta do gerente de TI da multinacional, o SAP roda muito bem em SQL Server e atende a maioria das empresas no qual utiliza esta configuração e benchmark dos dois bancos de dados são comuns, basta procurar no Google, segue aqui um exemplo : BenchMark DB2 1o vs SQL Server 2012 vs Oracle 11g R2 . Será que todas as empresas utilizam as novas features dos bancos de dados em seu sistema assim como faz a SAP?

Geralmente a solução do problema é trazida por um empresa de consultoria, porque este tipo de empresa lida com vários bancos de dados, de vários sistemas diferentes e seus especialistas conhecem a fundo varias bases de dados dos mais diferentes tipos, incluindo sistemas como o SAP, JDEdwardsMS Dynamics. É comum algumas consultorias que também fabricam software desenvolver soluções que completam ou interagem com estes ERPs e estes desenvolvedores ou consultores já estão calejados e sabem que nem tudo que existe por ai é uma maravilha, e nem todos podem ter o luxo de utilizar uma base de dados criada e assinada pela SAP, Oracle, Microsoft ou IBM. E as vezes ou na maioria delas a melhor solução é sim trocar o sistema.

O que acontece por ai?

Algumas empresas não sabem utilizar corretamente o banco, ressalto que utilizar um o banco de dados não é apenas possuir um desenvolvedor SQL que saiba escrever scripts. Já presenciei sistemas de empresas que existem há mais de 10 anos no mercado e ainda não aprenderam a utilizar um banco de dados relacional corretamente, muito menos já seguiram algum dia as melhores praticas. Em um caso em particular o banco de dados era Oracle e o sistema rodava em clientes de médio porte, e a frase constantemente ouvida dos clientes era: “O sistema é muito lento e toda vez que atualiza o sistema gera muitos erros”. Bom, neste caso o especialista da empresa não poderia dizer para trocar o banco de dados e ao analisar a base dados instantaneamente se notava vários problemas como: muitas chaves primarias, a não utilização de índice único, triggers em excesso, scripts SQL no mínimo duvidosos e lembro de um script do relatório de inventario que demorava mais ou menos 10 minutos para retornar 750 produtos.

É! isto existe por ai! E pergunto para você, isto é normal?

Alguns casos são demorados de resolver como o caso da empresa acima que vinha costurando scripts e programação sem metodologia a mais de 10 anos em um banco sem normalização e outros podem ser resolvidos facilmente como o caso de um empresa cooperativa de grande porte que possuía outras 98 empresas em seu grupo e precisava importar as notas fiscais de todas as empresas para um sistema de validação fiscal  que utiliza Microsoft SQL Server e os dados seriam extraídos de um sistema da IBM, este processo demorava mais de 4 horas . Utilizando novos scripts SQL, implementando técnicas de BULK foi possível reduzir o tempo do processo para importação de 5 anos de dados  de 98 empresas para 15 minutos.

Falta de Normalização

Falta de Normalização

O Verdadeiro Vilão

Podemos apontar de primeira alguns dos principais problemas como, falta de conhecimento da documentação do banco de dados em questão, pouca ou nenhuma normalização, não tratar o modelo de dados como um organismo vivo, que respira e cresce constantemente, o armazenamento inadequado dos dados de referência, não usar chaves estrangeiras ou restrições de verificação ou o uso excessivo dos mesmos, o não uso de domínios e padrões de nomenclatura  e não escolher chaves primárias adequadamente.

Em segundo lugar está o estilo de programação tanto para os scripts do banco dados como na linguagem que acessa os dados, é comum encontrar o uso excessivo de cursores, acessos repetitivos e não saber quando usar o conceito de múltiplos bancos de dados.

Vou ilustrar os parágrafos acima com um outro caso que também é muito comum, e refere-se a uso excessivo de chaves estrangeiras,  não saber a hora de optar por um sistema de banco de dados múltiplos e não incluir no projeto do sistema a previsão de crescimento do mesmo.

O problema ocorre porque inicialmente o projeto de um tipo de ferramenta que extrai dados fiscais para validação foi escrito somente para o banco de dados Oracle, ao longo dos anos com o investimento da Microsoft no MSSQL Server o banco de dados conseguiu um bom espaço no mercado e varias empresas de médio e grande porte o adquiriram, então a ferramenta da empresa em questão precisava trabalhar e rodar nos dois banco de dados. Mas o trabalho era árduo porque era preciso extrair os últimos cinco anos de dados fiscais da empresa e suas filiais e valida-los em horas.

Com o passar dos anos as obrigatoriedades vieram a ser maiores e a empresa proprietária da ferramenta precisava atender estas obrigatoriedades e o próprio mercado ditou a necessidade da ferramenta estar apta a rodar em um banco de dados que vinha ganhando cada vez mais espaço, é obvio que se um cliente possuísse uma licença para o banco de dados que rodava em seu sistema principal (MSSQL) não iria comprar uma licença mais cara (Oracle) somente para poder utilizar uma ferramenta e sim procurar outra ferramenta que atendia sua especificação técnica.

Primeiro a empresa tentou sozinha desenvolver para o novo banco de dados e encontrou varias dificuldades ao ter que descobrir também sozinha que os conceitos entre os bancos de dados não eram iguais e decidiu procurar ajuda especializada, ficou surpresa com o resultado, ao trabalhar com mais de um banco de dados a empresa conseguiu benefícios de desempenho também para o banco de dados no qual a empresa dominava e era especialista.

Porque para competir com o Oracle a Microsoft também usou como estratégia restringir os erros cometidos pelos desenvolvedores na arquitetura do banco de dados, meio que forçando o banco de dados SQL Server a ser escrito e normalizado o mais corretamente possível, assim ganhando mais performance, um exemplo são as chaves estrangeiras, estas requerem memoria e custam para serem interpretadas pelo Engine do banco de dados e a partir da versão 2005 do MSSQL a Microsoft começou a restringir chaves estrangeiras por tabela. No caso de um banco de dados único em um sistema multi-empresas é comum possuir mais de 253 tabelas que possuem uma chave estrangeira conectada a tabela de empresas, então a Microsoft começou a emitir um erro quando se tentava deletar ou alterar um registro de uma tabela que possuía tal quantidade de chaves estrangeiras, a simples clausula executada sobre esta tabela:

Delete from EMPRESA where ID_EMPRESA = 1

retorna o seguinte erro: QUERY TOO COMPLEX.

Capacidade máxima do MSSQL Server (Atente-se para a coluna chamada Foreign key table references per table):

link: http://msdn.microsoft.com/en-us/library/ms143432.aspx

Você pode ler e inserir dados na tabela normalmente, mas não pode mais apagar ou alterar os dados devido ao alto custo da query, apesar do Oracle ou outros bancos de dados permitirem tal modelagem a query executada sobre estas circunstancias também terá um custo maior para ser resolvida pelo Engine do banco de dados. Para uma modelagem mais compacta e sem excessos de objetos no banco de dados, um sistema pode possuir múltiplos bancos de dados, um exemplo de um sistema de grande porte com múltiplos bancos de dados é o JDEdwards da Oracle.

Grande Volume de Dados

Grande Volume de Dados

Processamento de grandes volumes de dados

É recomendado seguir melhores praticas para cada banco de dados e ler os White Papers escritos para suas ferramentas e quanto a regras de programação para sistemas que acessam dados você pode seguir o critério acima ou pode buscar conhecimento em empresas que já possuem este know-how como o caso da SAP.

Como é de conhecimento de todos os sistemas da SAP foram projetados para trabalhar com grande volume de dados e a SAP especifica 5 regras para se programar com os banco de dados: Oracle, Db2, Microsoft SQL Server e Informix. Apesar destas regras serem escritas para programas ABAP e Java e a arquitetura de dados do SAP R/3, elas também se aplicam a forma como outras linguagens de programação devem acessar o banco de dados:

  1. Mantenha o conjunto de resultados Pequeno.
  2. Minimizar a quantidade de dados transferidos.
  3. Minimizar o número de transferências de dados.
  4. Minimizar a Pesquisa Overhead.
  5. Reduzir a carga do banco de dados.

 

 

Para testar e checar seu programa ABAP você pode usar técnicas especiais que permitem que o desenvolvedor avalie a velocidade de execução de uma determinada rotina. Você pode medir uma rotina de seu programa criando um campo que retorna o tempo de execução de determinada expressão ou bloco de instruções usando o comando GET RUN TIME FIELD . Você pode também usar métodos estáticos da classe chamada CL_ABAP_RUNTIME para medir tempo de execução com alta precisão de tempo.

RUNTIME

RUNTIME

Exemplo:

Neste exemplo usamos técnicas especiais para medir o tempo de execução de rotinas ABAP, você pode notar que usamos dois métodos diferentes para medida.

Abap

*&---------------------------------------------------------------------*
*& Report  ZRUNTIMECAMPO
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Medir tempo de execução de um programa ABAP
*&---------------------------------------------------------------------*

REPORT  ZRUNTIMECAMPO.

* Declara campos para runtime
DATA : objTempo TYPE REF TO IF_ABAP_RUNTIME,
       tempo1   TYPE i,
       tempo2   TYPE i,
       tempo3   TYPE i,
       tempo4   TYPE i.

* Declara campos para calculo
DATA : Numero    TYPE i VALUE 15000,
       calculo1  TYPE i VALUE 1000,
       calculo2  TYPE i VALUE 2,
       expressao TYPE i.

* Mostra titulo
Write : / 'Medida em Microsegundos'  COLOR 3.
SKIP 2.
Write : / 'Variável'  COLOR 5.
SKIP 1.

* Cria primeira medida de tempo de execução
DO Numero TIMES.
   GET RUN TIME FIELD TEMPO1.
ENDDO.

Write : / 'Tempo de execução do primeiro looping - vazio: ', TEMPO1 COLOR 4.

* Cria segunda medida de tempo de execução
Do Numero TIMES.
   GET RUN TIME FIELD TEMPO2.
   EXPRESSAO = NUMERO * CALCULO1 / CALCULO2.
ENDDO.

* Medida de tempo atravez de um objeto Abap
Write : / 'Tempo de execução do segundo looping - calculo: ', TEMPO2 COLOR 6.
SKIP 1.

* Cria objeto
OBJTEMPO = CL_ABAP_RUNTIME=>CREATE_HR_TIMER( ).

Write : / 'Objeto'  COLOR 5.
SKIP 1.

* Medida de tempo por objeto
DO Numero TIMES.
   TEMPO3 = OBJTEMPO->GET_RUNTIME( ).
ENDDO.

Write : / 'Objeto - tempo final de execução - vazio: ', TEMPO3 COLOR 4.

* Zera variavel
EXPRESSAO = 0.

* Medida de tempo por objeto
DO Numero TIMES.
   TEMPO4 = OBJTEMPO->GET_RUNTIME( ).
   EXPRESSAO = NUMERO * CALCULO1 / CALCULO2.
ENDDO.

Write : / 'Objeto - tempo final de execução - calculo: ', TEMPO3 COLOR 6.

Em ABAP existem técnicas especiais que permitem criar além de programas dinâmicos como vimos no post anterior como também sub-rotinas temporárias. Você pode usar a instrução GENERATE SUBROUTINE POOL para criar sub-rotinas temporárias.

Esta declaração cria um pool de sub-rotina na área de memória principal do programa em execução. Você passa o código fonte do pool de sub-rotina para a tabela interna. A instrução retorna o nome do pool de sub-rotina gerada em um campo <prog> que deve ter tipo C. Você usa o nome contido em <prog> para chamar as sub-rotinas externas definidas na tabela interna através de chamadas de sub-rotinas dinâmicas.

Código Dinâmico

Código Dinâmico

Exemplo:

Neste exemplo criamos uma sub-rotina temporária na memoria do programa em execução.

Abap

*&---------------------------------------------------------------------*
*& Report  ZDINAMIC_INCLUDE
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Sub-rotinas Temporarias
*& Procedimento Dinamico - Tecnicas Especiais ABAP
*&---------------------------------------------------------------------*

REPORT  ZDINAMIC_INCLUDE.

* Cria variavel para rotina
DATA Codigo(72) OCCURS 11.

* cria variaveis para menssagem
DATA : Programa(16),
       Menssagem(150),
       Linha(3),
       Palavra(10),
       Desvio(3).

* Cria código dinamico
APPEND '* Desenvolvimento Aberto' TO CODIGO.
APPEND '* ----------------------' TO CODIGO.
APPEND '* ABAP Special Techniques ' TO CODIGO.
APPEND '*' TO CODIGO.
APPEND '* Subrotina temporaria' TO CODIGO.
APPEND '' TO CODIGO.
APPEND 'PROGRAM SUBROTINA.' TO CODIGO.
APPEND 'FORM MINHASUB.' TO CODIGO.
APPEND 'WRITE : / ''Está é minha subrotina temporaria'' COLOR 6.' TO CODIGO.
APPEND 'ENDFORM.' TO CODIGO.

* Gera subrotina
GENERATE SUBROUTINE POOL CODIGO
                    NAME PROGRAMA
                    MESSAGE MENSSAGEM
                    LINE LINHA
                    WORD PALAVRA
                    OFFSET DESVIO.

* Verifica retorno
IF SY-SUBRC <> 0.

* Se houver erro:
 WRITE: / 'ERRO na geração da linha', LINHA,
        / MENSSAGEM,
        / 'Word:', PALAVRA, 'at offset', DESVIO.
ELSE.

*  Se houver sucesso:
 WRITE: / 'Técnicas Especiais ABAP - Sub-rotinas temporarias'.
 SKIP 1.
 WRITE: / 'O nome da sub rotina é ' COLOR 3, PROGRAMA COLOR 5.
 SKIP 2.
 PERFORM MINHASUB IN PROGRAM (PROGRAMA).

ENDIF.

Existem vários métodos para se conectar no banco de dados SQL Server através da linguagem Python, você pode criar uma conexão usando módulos escritos por terceiros como o pyMSSQL, você pode usar as biblioteca win32 através do modulo pyWin32 ou você se conectar usando o framework e ADO.NET usando o IronPython. Neste post usaremos o pyWin32 Extension para executar este trabalho, você pode baixar esta extensão no seguinte site:

Download: http://sourceforge.net/projects/pywin32/

Microsoft SQL Server - Python

Microsoft SQL Server – Python

Conectando ao Microsoft SQL Server

1 – Após baixar e instalar a extensão para o Python Win32 você precisa criar uma conexão ODBC para SQLSERVER, você pode optar por uma conexão ODBC win32 ou x64, para isto acesse o painel de controle, ferramentas administrativas e fontes de dados ODBC e preencha e teste a conexão com o seu servidor MSSQL:

MSQL -DNS

MSQL -DNS

2 – Abra sua IDE Python e utilize o código abaixo.

Exemplo:

Neste exemplo construiremos uma conexão com o banco de dados SQL Server através da extensão pyWin32 e utilizaremos um DNS ODBC para criar uma conexão com o banco de dados.

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# ConexaoMSSQL.py

# importa modulos
from Tkinter import *
import tkMessageBox
import odbc

# Cria formulario
formulario = Tk(className='Microsoft SQL Server')
formulario.geometry("300x200+300+300")

# Cria janela para menssagem
janela = Tk()
janela.wm_withdraw()

# Evento para o botão
def conectar():
    # Cria string de conexão
    sconexao = edb.get() + "/" +  eusuario.get() + "/" + esenha.get()
    try:
        con = odbc.odbc(sconexao)
        tkMessageBox.showinfo(title="Menssagem", message="Conectado com Sucesso!", parent=janela)
    except ValueError:
        tkMessageBox.showinfo(title="Menssagem", message="Erro de Conexão", parent=janela)

# Cria componentes
titulo = Label(formulario, text="MSSQL Express 2012 - Python")

lusuario = Label(formulario, text="Digite seu usuário:")
lsenha = Label(formulario, text="Digite sua senha:")
ldb = Label(formulario, text="Digite o DNS ODBC:")

eusuario = Entry(formulario)
esenha = Entry(formulario, show="*")
edb = Entry(formulario)

botao = Button(formulario, text="Conectar", command=conectar)

# Cria layout de tela
titulo.grid(row=0, sticky=W+E+N+S, pady=10)
lusuario.grid(row=1, sticky=W, padx=20)
eusuario.grid(row=1, column=1, pady=5)
lsenha.grid(row=2,sticky=W, padx=20)
esenha.grid(row=2, column=1, pady=5)
ldb.grid(row=3, sticky=W, padx=20)
edb.grid(row=3, column=1, pady=5)
botao.grid(row=5, sticky=W, pady=20, padx=20)

# Loop do tcl
mainloop()

 

A API ibm_db oferece uma variedade de funções úteis para acessar e manipular dados em um banco de dados de um servidor de dados IBM ®. A API inclui funções para se conectar a um banco de dados, executar e preparar instruções SQL, buscar linhas de conjuntos de resultados, chamar procedimentos armazenados, finalizar e reverter transações, manipular tratamento de erros e recuperação de metadados.

IBM DB2 - Python

IBM DB2 – Python

Python DBI driver for DB2 (LUW, zOS, i5) and IDS

Essa extensão é a implementação de banco de dados com especificação da API Python v2.0. A extensão suporta DB2 (LUW, zOS, i5) e IDS (Informix Dynamic Server)

Download: https://pypi.python.org/pypi/ibm_db/

Instalação:

Para instalar a API você pode compilar o código fonte ou utilizar as extensões já compiládas, copiando o arquivo ibm_db.pyd para o diretório de DLL da sua instalação do Python.

Diretório: C:\Python27\DLLs\ibm_db.pyd

Exemplo:

Neste exemplo usamos a API de conexão para o IBM DB2 para efetuar uma conexão com o banco de dados DB2 Express-C.

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# ConexaoDB2py

# importa modulos
from Tkinter import *
import tkMessageBox
import ibm_db

# Cria formulario
formulario = Tk(className='IBM DB2 Express-C')
formulario.geometry("300x200+300+300")

# Cria janela para menssagem
janela = Tk()
janela.wm_withdraw()

# Evento para o botão
def conectar():
    # Cria string de conexão
    sconexao = "DATABASE=" + edb.get() + \
               ";HOSTNAME=localhost;PORT=50000;PROTOCOL=TCPIP;" + \
               "UID=" + eusuario.get() + ";" + \
               "PWD=" + esenha.get()
    try:
        con = ibm_db.connect(sconexao, "", "")
        tkMessageBox.showinfo(title="Menssagem", message="Conectado com Sucesso!", parent=janela)
    except ValueError:
        tkMessageBox.showinfo(title="Menssagem", message="Erro de Conexão", parent=janela)

# Cria componentes
titulo = Label(formulario, text="IBM DB2 - Python")

lusuario = Label(formulario, text="Digite seu usuário:")
lsenha = Label(formulario, text="Digite sua senha:")
ldb = Label(formulario, text="Digite o database:")

eusuario = Entry(formulario)
esenha = Entry(formulario, show="*")
edb = Entry(formulario)

botao = Button(formulario, text="Conectar", command=conectar)

# Cria layout de tela
titulo.grid(row=0, sticky=W+E+N+S, pady=10)
lusuario.grid(row=1, sticky=W, padx=20)
eusuario.grid(row=1, column=1, pady=5)
lsenha.grid(row=2,sticky=W, padx=20)
esenha.grid(row=2, column=1, pady=5)
ldb.grid(row=3, sticky=W, padx=20)
edb.grid(row=3, column=1, pady=5)
botao.grid(row=5, sticky=W, pady=20, padx=20)

# Loop do tcl
mainloop()