Database – Sequence e Identity – Oracle – IBM DB2 – Microsoft SQL Server – MFC – C++

Publicado: 26 de setembro de 2014 em C/C++

Uma Sequence é um objeto de banco de dados encontrado nos bancos de dados Oracle e IBM DB2, que permite a geração automática de valores, tais como números de identificação. Sequências são ideais para a tarefa de gerar valores de chaves únicas. Os aplicativos podem usar sequências para evitar possíveis problemas de simultaneidade e de desempenho resultantes de valores de coluna. A vantagem que tem sobre as  sequências de números criados fora do banco de dados é que o servidor de banco de dados mantém o registro dos números gerados e nenhum tipo de acidente no banco de dados causará números duplicados.

Sequence & Identity - C++

Sequence & Identity – C++

Identity é encontrado no banco de dados Micosoft SQL Server e é muito similar ao Sequence e possui o mesmo objetivo que é de criar números sequenciais, porem não é um objeto do banco de dados e sim uma propriedade de uma coluna pertencente a uma tabela. Quando você insere um valor em uma tabela que possui uma propriedade Identity você deve excluir o campo referente a esta coluna da clausula SQL, sendo assim o MSSQL Server é o único banco de dados que permite que a quantidade de colunas na linha Values da instrução Insert seja diferente da quantidade de colunas na tabela do banco de dados.

sequence-3-sql-server

MSSQL – Identity – Propriedades

Para saber mais detalhes sobre os recursos dos objetos Sequences ou da propriedade Identity recomendamos que você utilize os links oficiais de cada banco de dados:

Oracle: Sequence
IBM DB2: Sequence
MSSQL Server: Identity

Algo extremamente útil sobre Sequence ou Identity

Utilizar um objeto ou uma propriedade auto incremento é o método correto para criar IDs automáticos no banco de dados, nunca utilize uma Trigger para executar este procedimento, pois deste modo você esta reduzindo sensivelmente a performance do banco de dados, visto que você precisa de acessos e objetos extras para executar a mesma função.

Para valores de Sequence ou Identity que são utilizados fora do banco de dados, por exemplo, números de sequência usados ​​para identificadores externos (números de cheques bancários ou outros), se o banco de dados é recuperado para um ponto no tempo antes de uma falha, então isso poderia causar a geração de valores duplicados para algumas sequências. Para evitar possíveis valores duplicados, bancos de dados que usam valores de sequência fora do banco de dados não deve ser recuperado para um ponto anterior no tempo.

Visual Studio

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:

Visual Studio - Design - cpp

Visual Studio – Design – MFC Dialog Based

 

Exemplo:

Neste exemplo utilizamos uma Sequence para os bancos de dados Oracle e IBM DB2 e uma propriedade Identity para o banco de dados MSSQL para criar identificadores automáticos para a coluna chave de uma tabela.

SQL

Oracle

-- Cria sequencia
CREATE SEQUENCE Sequencia_seq
 START WITH     1
 INCREMENT BY   1
 NOCACHE
 NOCYCLE;

-- Cria tabela
CREATE TABLE SEQUENCIA (
   Identificador   NUMBER(10),
   Nome            VARCHAR(30),
   Sobrenome       VARCHAR(70),
   Cargo           VARCHAR(30),
   Salario         Decimal(9,2));

 -- Testa sequencia
insert into SEQUENCIA VALUES (Sequencia_seq.NEXTVAL ,'Teste','Teste Sobrenome','Programador',2234.56);

-- verifica resultado
SELECT * FROM SEQUENCIA

IBM DB2

-- Cria Sequencia
CREATE SEQUENCE Sequencia_seq
 START WITH     1
 INCREMENT BY   1
 NOCACHE
 NOCYCLE;

-- Cria tabela
CREATE TABLE SEQUENCIA (
   Identificador   INTEGER,
   Nome            VARCHAR(30),
   Sobrenome       VARCHAR(70),
   Cargo           VARCHAR(30),
   Salario         Decimal(9,2));

 -- Testa Sequencia
insert into SEQUENCIA VALUES (Sequencia_seq.NEXTVAL ,'Teste','Teste Sobrenome','Programador',2234.56);

-- Verifica resultado
Select * from SEQUENCIA;

MSSQL

-- Cria tabela / Identity
CREATE TABLE SEQUENCIA(
	Identificador int IDENTITY(1,1) NOT NULL,
	Nome          nvarchar(30) NULL,
	Sobrenome     nvarchar(70) NULL,
	Cargo         nvarchar(30) NULL,
	Salario       decimal(9, 2) NULL);

-- Testa identação
insert into SEQUENCIA VALUES ('Teste','Teste Sobrenome','Programador',2234.56);

-- Verifica tabela
select * from SEQUENCIA;

C++

Classe – Definição – arquivo .h

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

#pragma once

// Inclui classe de banco de dados MFC
#include "afxdb.h"
#include "afxcmn.h"
#include "afxwin.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;
	
};

Classe – Implementação – 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"user", L"p@55w0rd");
	}

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

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

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


	// DB2 e Oracle utilizam sequence
	// SQL Server utiliza o Identity
	// Como é um objeto atrelado ao campo
	// Necessita ser suprimido da clausula SQL
	if (bancodedados != "mssql") 
	{

		insereSql = L"insert into SEQUENCIA VALUES (Sequencia_seq.NEXTVAL ,\'Teste\',\'Teste Sobrenome\',\'Programador\',2234.56)";

	}
	else
	{
		insereSql = L"insert into SEQUENCIA VALUES (\'Teste\',\'Teste Sobrenome\',\'Programador\',2234.56)";

	}
	
	// Executa instrução SQL
	db.ExecuteSQL(insereSql);
		
	// Declara instrução SQL
	CString sql = L"SELECT * FROM SEQUENCIA ORDER BY 1 DESC";

	// Abre set de dados
	dados.Open(CRecordset::forwardOnly, sql);

	// 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);	
}
Publicidade

Deixe um comentário

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

Logo do WordPress.com

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

Foto do Facebook

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

Conectando a %s