SAP MaxDB – Aplicações Enterprise com C++ – Win32 – MFC

Publicado: 14 de novembro de 2014 em Abap, C/C++

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

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:

SAP - Servidor de Aplicação - e Banco de dados - NetWeaver/MaxDB

SAP – Servidor de Aplicação – e Banco de dados – NetWeaver/MaxDB

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:

NSP - NetWeaver Database

NSP – NetWeaver Database

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:

Tabela Não Transparente

Tabela Z Não Transparente

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:

ODBC 32bit

ODBC 32bit

5 – Crie uma nova fonte de dados do usuário escolha o driver NSP ou o driver apropriado e clique em concluir:

ODBC SQLSTUDIO

ODBC SQLSTUDIO

6 – Preencha os dados de conexão com o servidor e o banco de dados e finalize:

Dados Servidor

Dados Servidor

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:

Design Time

Design Time

8 – Utilize o código abaixo para manipular dados utilizando o SAP MaxDB:

C++ - Programa

C++ – Programa

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:

Stored Procedure - Abap

Stored Procedure – Abap

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);
}
Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s