SAP MaxDB é um banco de dados estratégico criado para rodar em todas as soluções SAP e substituir os bancos de dados Oracle, IBM DB2 e MSSQL Server tornando as soluções SAP mais acessíveis em termos de custo para clientes de grande e médio porte. O SAP MaxDB foi construído como uma solução open source baseado em MySQL sob a licença GNU GPL, as versão anteriores do MaxDB ainda são mantidas pela comunidade open source mas a SAP não contribui mais com estas versões.
Ao longo dos últimos anos, a tecnologia SAP MaxDB continuou a evoluir com investimentos muito significativos em inovações e essas inovações não são em código aberto. Assim o mais recente produto SAP MaxDB não é open source, entretanto ele é gratuito em sua versão comunitária para uso com aplicações não SAP e possui licença comercial para uso com aplicações SAP.
Com 40 anos de inovação atuando em mais de 130 países e com mais de 100 mil clientes que utilizam soluções SAP, o SAP MaxDB ainda é um banco de dados jovem mas conta com mais de 6.500 clientes em 15.000 instalações mais soluções que utilizam liveCache e Content Server.
SAP MaxDB: http://maxdb.sap.com/
SAP MaxDB e C++ MFC
O C++ MFC utiliza as classes de fundação Microsoft e é a linguagem padrão para se desenvolver aplicativos Desktop C++ para Windows, você precisa no mínimo de uma versão profissional do Visual Studio para utilizar este framework.
A SAP disponibiliza uma API para utilizar o MaxDB com a linguagem de programação C++ utilizando os sistemas operacionais Unix, Linux e Windows, possibilitando integrar soluções Enterprise SAP que utilizam o banco de dados MaxDB com aplicações escritas em C++ ou permite que aplicações C++ utilizem o SAP MaxDB gratuitamente também em soluções que não possuem o intuito de integrar dados com os sistemas SAP.
Softwares Requeridos
Para utilizar este walkthrough completo integrando uma solução C++ com a linguagem de programação ABAP, você precisa instalar vários software entres eles o NetWeaver Application Server ABAP no qual já possui uma instalação completa do ambiente de desenvolvimento SAP com uma instancia do banco de dados MaxDB, caso queira utilizar somente o lado C++ você pode baixar o SAP MaxDB diretamente da SAP Store:
NetWeaver Application Server ABAP: Mini SAP
Download SAP MaxDB sistemas não SAP: SAP Store
SAP MaxDB SQL Studio: Desenvolvimento Aberto walkthrough
API C++ e Drivers ODBC
O Microsoft Fundation Classes permite utilizar suas classes para conectar ao MaxDB de um modo simples através do protocolo padrão ODBC, no entanto os drivers ODBC disponibilizados pela SAP não possuem a mesma arquitetura para aplicativos win32 (código nativo) x64, então precisamos utilizar o driver 32bit disponibilizado pelo SAP MaxDB SQL Studio.
Caso não queira utilizar as classes MFC, a instalação do SAP MaxDB incluída nos produtos SAP como o núcleo de desenvolvimento do sistema SAP R/3 chamado de NetWeaver Application Sever ABAP já comtempla uma API C++ para que você possa acessar o banco de dados MaxDB e se encontra no seguinte local:
C:\sapdb\clients\NSP\sdk\sqldbc\incl
C:\sapdb\NSP\db\doc\FirstSteps\SQLDBC
Conectando ao MaxDB NSP com C++
1 – Caso utilize este tutorial com o NetWeaver primeiro tenha certeza que servidor de aplicação e a instancia SAP do banco de dados está rodando, caso utilize apenas o MaxDb e C++ ignore este passo:
2 – Abra o SQL Studio utilizando o servidor MaxDB e o banco de dados NSP ou seu próprio banco de dados caso não utilize o sistema SAP:
3 – Crie uma tabela Z que significa uma tabela não SAP Standard que não será transparente no conceito do dicionário de dados do sistemas SAP para isto utilize o script logo abaixo, não se assuste para desenvolvedores não SAP isto é apenas uma tabela comum do banco de dados:
4 – Utilizaremos os drivers ODBC do SAP MaxDB SQL Studio. No painel de controle escolha ferramentas administrativas e fonte de dados ODBC de 32bit, em drivers verifique seu driver NSP:
5 – Crie uma nova fonte de dados do usuário escolha o driver NSP ou o driver apropriado e clique em concluir:
6 – Preencha os dados de conexão com o servidor e o banco de dados e finalize:
7 – No Visual Studio crie uma solução MFC Dialog Based e disponha na tela um Static Text, um List Control e um Button, utilize a figura abaixo para o design:
8 – Utilize o código abaixo para manipular dados utilizando o SAP MaxDB:
9 – Para utilizar o ABAP para ler ou gravar dados nesta mesma tabela não transparente utilizando uma Stored Procedure no MaxDB através de códigos Native SQL, utilize o link abaixo:
Programa SAP – ABAP Native SQL: MaxDB Stored Procedure parâmetros IN e OUT
Caso conecte em um banco de dados MaxDB utilizando soluções SAP tenha em mente que você deve respeitar o conceito de dados dos sistemas SAP e verificar os termos de garantia de cada produto SAP, visto que este método ao contrario do RFC ignora a camada de banco de dados SAP e o dicionário de dados ABAP.
Como você pode verificar na imagem acima no ambiente ABAP o valor flutuante não vem formatado por padrão como estão acostumados os desenvolvedores SAP que utilizam instruções Open SQL e o dicionário ABAP no entanto você pode utilizar campos criados no dicionário apenas para a manipulação do valor de saída da Stored Procedure neste caso você deve alinhar os tipos de dados entre as aplicações C++ e aplicações ABAP.
Exemplo:
Neste exemplo utilizamos a linguagem de programação C++ para conectar ao banco de dados SAP MaxDB em uma instancia do banco de dados do NetWeaver e integrar uma tabela não transparente que pode ser manipulada tanto do lado C++ como dentro do sistema SAP utilizando Native SQL.
SQL – SAP MaxDB
-- Cria tabela no schema SAPNSP
CREATE TABLE SAPNSP.ZFUNCIONARIO
(
ID_FUNCIONARIO INT,
NOME VARCHAR (30),
SOBRENOME VARCHAR(70),
CARGO VARCHAR(30),
SALARIO DECIMAL(9,2)
)
-- Insere dados na tabela
Insert into SAPNSP.ZFUNCIONARIO values (1,'Steve','Gates','Programador',2550.56)
Insert into SAPNSP.ZFUNCIONARIO values (2,'Bill','Jobs','Diretor',5143.71)
CPP – arquivo h
// ConexaoSapMaxDBcppDlg.h : header file
//
#pragma once
// Inclui classe de banco de dados MFC
#include "afxdb.h"
#include "afxcmn.h"
// CConexaoSapMaxDBcppDlg dialog
class CConexaoSapMaxDBcppDlg : public CDialogEx
{
public:
CConexaoSapMaxDBcppDlg(CWnd* pParent = NULL); // standard constructor
enum { IDD = IDD_CONEXAOSAPMAXDBCPP_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
protected:
HICON m_hIcon;
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
// Cria métodos e objetos da classe
CDatabase db;
void conectarDB(CString dns, CString usuario, CString senha);
afx_msg void OnBnClickedButton1();
CListCtrl m_tabela;
};
CPP – arquivo cpp
// ConexaoSapMaxDBcppDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ConexaoSapMaxDBcpp.h"
#include "ConexaoSapMaxDBcppDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CConexaoSapMaxDBcppDlg dialog
CConexaoSapMaxDBcppDlg::CConexaoSapMaxDBcppDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CConexaoSapMaxDBcppDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CConexaoSapMaxDBcppDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_tabela);
}
BEGIN_MESSAGE_MAP(CConexaoSapMaxDBcppDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CConexaoSapMaxDBcppDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
// CConexaoSapMaxDBcppDlg message handlers
BOOL CConexaoSapMaxDBcppDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Inicializa dialogo
// 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; // return TRUE unless you set the focus to a control
}
void CConexaoSapMaxDBcppDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
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;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
HCURSOR CConexaoSapMaxDBcppDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CConexaoSapMaxDBcppDlg::OnBnClickedButton1()
{
// campo de dado da tabela
CString m_campo;
// Abre conexão
// O SAP MAXDB requer usuário e senha em caracteres UPPERCASE
conectarDB(L"SAPMAXDB32", L"SAPNSP", L"PASSWORD");
// Cria um set de dados
CRecordset dados(&db);
// Executa instrução SQL
dados.Open(CRecordset::forwardOnly, L"Select * From SAPNSP.ZFUNCIONARIO Order by 1 DESC");
// 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 CConexaoSapMaxDBcppDlg::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);
}










