Na linguagem de programação C++ um desenvolvedor pode utilizar as classes de fundação da Microsoft chamadas de MFC para desenvolver programas capazes de executar instruções SQL diretas utilizando a classe CDatabase ao invés de utilizar um DataSource.
A maioria dos comandos para manipular uma fonte de dados são emitidos através de um objeto CRecordSet que suporta os comandos para a seleção de dados, inserir novos registros, excluir registros e edição de registros. No entanto, nem todas as funcionalidades do ODBC são suportadas diretamente pelas classes de banco de dados, então as vezes, você precisa fazer uma chamada SQL direta com a instrução ExecuteSQL.
CDatabase::ExecuteSQL
Chame este membro da função quando você precisar executar um comando SQL diretamente.
Visual Studio
Para criar um programa que executa as quatro operações básicas de um banco de dados em uma aplicação C++ MFC Dialog Based, siga os seguintes passos:
1 – Crie um novo projeto C++ e disponha os componentes como na imagem abaixo:
3 – Use o Class Wizard para introduzir a mensagem WM_SHOWWINDOW, e crie as variáveis e os eventos adequados para cada componente, para isto você pode se basear no método DoDataExchange e BEGIN_MESSAGE_MAP encontrados no código abaixo:
Exemplo:
Este programa executa as quatro operações básicas em diferentes bancos de dados, atente-se para o padrão de campos do Microsoft SQL Server, que por default utilizando a classe CDatabase o torna case-sensitive.
C++
Arquivo .h
// CamposcppDlg.h : header file // #pragma once // Inclui classe de banco de dados MFC #include "afxdb.h" #include "afxwin.h" // CCamposcppDlg dialog class CCamposcppDlg : public CDialogEx { public: CCamposcppDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data enum { IDD = IDD_CAMPOSCPP_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: HICON m_hIcon; // Generated message map functions virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() public: // Cria métodos e objetos da classe CDatabase db; // Esta variavel define o banco de dados // oracle = Oracle Database // db2 = IBM DB2 // mssql = MSSQL Server CString m_db = L"oracle"; // Conecta ao banco de dados void conectarDB(CString banco); afx_msg void OnBnClickedButton1(); CEdit m_pesquisa; CEdit m_codigo; CEdit m_pnome; CEdit m_snome; CEdit m_cargo; CEdit m_salario; afx_msg void OnBnClickedButton2(); afx_msg void OnShowWindow(BOOL bShow, UINT nStatus); afx_msg void OnBnClickedButton3(); afx_msg void OnBnClickedButton4(); afx_msg void OnBnClickedButton5(); CButton m_apagar; CButton m_novo; };
Arquivo .cpp
// CamposcppDlg.cpp : implementation file // #include "stdafx.h" #include "Camposcpp.h" #include "CamposcppDlg.h" #include "afxdialogex.h" #ifdef _DEBUG #define new DEBUG_NEW #endif CCamposcppDlg::CCamposcppDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CCamposcppDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CCamposcppDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDIT6, m_pesquisa); DDX_Control(pDX, IDC_EDIT1, m_codigo); DDX_Control(pDX, IDC_EDIT2, m_pnome); DDX_Control(pDX, IDC_EDIT3, m_snome); DDX_Control(pDX, IDC_EDIT4, m_cargo); DDX_Control(pDX, IDC_EDIT5, m_salario); DDX_Control(pDX, IDC_BUTTON5, m_apagar); DDX_Control(pDX, IDC_BUTTON2, m_novo); } BEGIN_MESSAGE_MAP(CCamposcppDlg, CDialogEx) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, &CCamposcppDlg::OnBnClickedButton1) ON_BN_CLICKED(IDC_BUTTON2, &CCamposcppDlg::OnBnClickedButton2) ON_WM_SHOWWINDOW() ON_BN_CLICKED(IDC_BUTTON3, &CCamposcppDlg::OnBnClickedButton3) ON_BN_CLICKED(IDC_BUTTON4, &CCamposcppDlg::OnBnClickedButton4) ON_BN_CLICKED(IDC_BUTTON5, &CCamposcppDlg::OnBnClickedButton5) END_MESSAGE_MAP() BOOL CCamposcppDlg::OnInitDialog() { CDialogEx::OnInitDialog(); SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE); return TRUE; } void CCamposcppDlg::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 CCamposcppDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } // ************************ Desenvolvimento Aberto // Nosso código começa aqui void CCamposcppDlg::conectarDB(CString banco) { // Cria string de conexão CString dns, usuario, senha; // Define banco de dados if (banco == "oracle") { dns = L"OracleXE"; usuario = L"daberto"; senha = L"p@55w0rd"; } if (banco == "db2") { dns = L"IBMDB2"; usuario = L"db2admin"; senha = L"p@55w0rd"; } if (banco == "mssql") { dns = L"MSSQLSERVER"; usuario = L"devaberto"; senha = L"p@55w0rd"; } // 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); } void CCamposcppDlg::OnBnClickedButton1() { // Define variaveis CString codigo; CString m_campo; // Referincia objeto statico CWnd * p_rotulo; // Associa objeto statico p_rotulo = GetDlgItem(IDC_Rotulo); p_rotulo->SetWindowTextW(L"Database - Fields - " + m_db); // Conecta ao banco de dados conectarDB(m_db); // Cria um set de dados CRecordset dados(&db); // Cria pesquisa m_pesquisa.GetWindowTextW(codigo); dados.Open(CRecordset::forwardOnly, L"Select * From FUNCIONARIOS Where ID_FUNCIONARIO = " + codigo); // Retorna dados por nome de campo e os exibe // Oracle e o DB2 transformam os nomes de campos para maiusculo, // basta efetuar um select na tabela de cada banco e você verá // O MSSQL não faz esta mudança sendo assim você precisa mudar os campos // do banco de dados MSSQL para que fique compativel com o ORACLE e DB2 ou // encontrará um erro ao tentar utilizar a tabela que criamos anteriormente. dados.GetFieldValue(L"ID_FUNCIONARIO", m_campo); m_codigo.SetWindowTextW(m_campo); dados.GetFieldValue(L"NOME", m_campo); m_pnome.SetWindowTextW(m_campo); dados.GetFieldValue(L"SOBRENOME", m_campo); m_snome.SetWindowTextW(m_campo); dados.GetFieldValue(L"CARGO", m_campo); m_cargo.SetWindowTextW(m_campo); dados.GetFieldValue(L"SALARIO", m_campo); m_salario.SetWindowTextW(m_campo); // Fecha o set de dados e a conexão dados.Close(); db.Close(); } void CCamposcppDlg::OnBnClickedButton2() { // Limpa componentes m_codigo.SetWindowTextW(NULL); m_pnome.SetWindowTextW(NULL); m_snome.SetWindowTextW(NULL); m_cargo.SetWindowTextW(NULL); m_salario.SetWindowTextW(NULL); // Define foco CEdit* pesquisa; pesquisa = (CEdit*)GetDlgItem(IDC_EDIT1); GotoDlgCtrl(pesquisa); } void CCamposcppDlg::OnShowWindow(BOOL bShow, UINT nStatus) { CDialogEx::OnShowWindow(bShow, nStatus); // Define foco inicial CEdit* pesquisa; pesquisa = (CEdit*)GetDlgItem(IDC_EDIT6); GotoDlgCtrl(pesquisa); } // Cria método de menssagem int menssagem(bool correto, LPCWSTR texto) { LPCWSTR msg; if (correto) { msg = texto; } else { msg = texto; } // Cria nova caixa de menssagens int msgboxID = MessageBox( NULL, msg, (LPCWSTR)L"Conexão", MB_ICONWARNING | MB_OK | MB_DEFBUTTON2 ); switch (msgboxID) { case IDOK: break; } return msgboxID; } // Clique do botão inserir void CCamposcppDlg::OnBnClickedButton3() { // Define variaveis para componentes CString codigo; CString pnome; CString snome; CString cargo; CString salario; // conecta ao banco de dados conectarDB(m_db); // Recupara texto dos componentes m_codigo.GetWindowTextW(codigo); m_pnome.GetWindowTextW(pnome); m_snome.GetWindowTextW(snome); m_cargo.GetWindowTextW(cargo); m_salario.GetWindowTextW(salario); // Troca ponto decimal para o banco de dados int i = salario.Replace(L",", L"."); // Cria instrução SQL CString sql = L"Insert into FUNCIONARIOS values ( " + codigo + ", " + "'" + pnome + "', " + "'" + snome + "', " + "'" + cargo + "', " + salario + ")"; // Executa SQL try { db.ExecuteSQL(sql); menssagem(true, L"Dados inseridos com sucesso!"); db.Close(); } catch (CDBException* pe) { menssagem(false, L"Erro ao inserir dados."); db.Close(); } } // botão Updata void CCamposcppDlg::OnBnClickedButton4() { CString codigo; CString pnome; CString snome; CString cargo; CString salario; CString troca; conectarDB(m_db); m_codigo.GetWindowTextW(codigo); m_pnome.GetWindowTextW(pnome); m_snome.GetWindowTextW(snome); m_cargo.GetWindowTextW(cargo); m_salario.GetWindowTextW(salario); int i = salario.Replace(L",", L"."); CString sql = L"Update FUNCIONARIOS set ID_FUNCIONARIO = " + codigo + ", " + "NOME = '" + pnome + "', " + "SOBRENOME = '" + snome + "', " + "CARGO = '" + cargo + "', " + "SALARIO = " + salario + " " + "Where ID_FUNCIONARIO = " + codigo; try { db.ExecuteSQL(sql); menssagem(true, L"Dados alterados com sucesso!"); db.Close(); } catch (CDBException* pe) { menssagem(false, (LPWSTR)pe); db.Close(); } } void CCamposcppDlg::OnBnClickedButton5() { CString codigo; conectarDB(m_db); m_codigo.GetWindowTextW(codigo); CString sql = L"Delete From FUNCIONARIOS Where ID_FUNCIONARIO = " + codigo; try { db.ExecuteSQL(sql); // Executa clique do botão novo // crie variavel m_novo SendMessage(WM_COMMAND, MAKEWPARAM(IDC_BUTTON2, BN_CLICKED), (LPARAM)m_novo.m_hWnd); menssagem(true, L"Dados apagados com sucesso!"); db.Close(); } catch (CDBException* pe) { menssagem(false, L"Erro ao apagar dados."); db.Close(); } }