Conexão genérica com banco de dados fabiopaganini@hotmail.com Quem de nós programadores já não teve uma ponta de duvida sobre qual banco de dados utilizar em nossas aplicações? Você pode até não ter passado ainda por isto, mas a grande maioria já passou ou está passando. Agora vejamos, nós programadores, macacos velhos que estamos convivendo com estas informações, imagina como será a duvida de seus clientes que muitas vezes não sabem quase nada sobre banco de dados e ainda terão que pagar por ele em certos casos. Você como programador, desenvolvedor de sistemas corporativos, não poderá permitir que seu clientes estejam preso e vinculados por um banco de dados, isto porque você pretende não trabalhar somente para ele, e sim focar um grande numero de clientes. Veja alguma das ocasiões que fortalecem a obrigação de uma aplicação comercial não ser destinada para um único tipo de banco de dados: - Clientes são clientes, independente se são de pequeno, médio e grande porte. Juntamente com isto, a quantidade de dados desejados serão diferente para cada caso. Não faça seu cliente de pequeno porte ter que comprar um SqlServer ou um DB2 da IBM, pois são caros e estarão além das necessidades dele, e também não ofereça um MySQL ou um ACCESS para um cliente de grande porte, pois logo de cara, com a grande concorrência de dados e a quantidade de registros farão do seu sistema a maior dor de cabeça de seu cliente, o que te trará uma má imagem e então o possível cancelamento de contrato e a perca do cliente. - Alguns clientes possivelmente já trabalharam com outro sistema, e se eles pagaram caro para ter um banco de dados a qual o seu sistema não foi destinado, o que você fará? Obrigará o seu cliente a comprar o banco de dados que sua aplicação trabalha? Fazer com que ele desperdice a licença comprada para obter o MySQL? Ou você vai editar todo o seu programa para que ele seja compatível com o novo banco de dados? Isto é inviável para ambas as partes, pois você cobraria uma fortuna a mais para isto e o cliente não iria querer pagar, e novamente você perderia a possibilidade de um novo contrato. Fora que se sua aplicação for muito grande, muitas vezes alguns itens poderão ser esquecidos de tal alteração e então futuros bugs ocorrerão, destruindo sua imagem de um profissional do ramo. - O cliente está apenas iniciando com a empresa e pretende futuramente expandir seu DB, o que vc fará? Ira no futuro criar um novo programa para ele? Assim é fácil de ganhar dinheiro, mas também é fácil de perdê-lo.
Convenceu-se? Talvez não, pois você nem saiba de a onde o objetivo deste cenário que estou criando quer chegar. O objetivo é mostrar que facilmente o seu programa pode ser compatível com todos os bancos de dados existente sem a necessidade de alterar todo o seu sistema, e a conexão genérica está aqui para auxiliar. Criando a conexão genérica 1. Inicie um novo projeto Windows Form Application no VisualBasic. 2. Adicione um novo modulo chamado Conexao dados: Agora temos que importar alguns dos mais comuns namespaces de provedores de Imports System Imports System.Data.Common Imports System.Data.OleDb Imports System.Data.Odbc Imports System.Data.SqlClient Imports System.Data.SqlTypes Agora temos que informar as possiveis strings de conexões: Public Module conexao Private strodbcconn As String = "Driver={Microsoft Access Driver (*.mdb)};dbq=c:\neoartvision\neosis Cobrança\DATA\NeoSisDat.mdb;Uid=Admin;Pwd=" Private strconn As String = "Provider=SQLNCLI.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=NeoSisDat;Data Source=apserver\mssql" Private stroledbconn As String = "Provider=SQLNCLI.1;Integrated Security=SSPI;Persist Security Info=True;Passwort=123456;User ID=neoart;Initial Catalog=NeoSisDat;Data Source=vmserver\mssql" Private strmsdeconn As String = "Persist Security Info=True;User ID=neoart;Password=123456;Initial Catalog=NeoCred;Data Source=APSERVER"
Estas strings podem ser algeradas apartir do codigo em forumlários de configuraçoes ou até mesmo no registro do windows. Basta apenas implementar este codigo. Agora temos que criar uma string que informe qual banco de dados estamos usando: Private VARConectionType As String = "MSDE Onde a partir de agora, o sistema passara a usar um banco de dados MSDE. Devemos agora criar uma função que retorna uma conexão, ela será útil para que no seu sistema vc ao inves de criar uma conexão, você cria uma referencia a esta função. Public Function GetConnection() As System.Data.IDbConnection Return New System.Data.OleDb.OleDbConnection(StringDeConexao) Return New System.Data.SqlClient.SqlConnection(StringDeConexao) Return New System.Data.Odbc.OdbcConnection(StringDeConexao) Return Nothing Teremos vários formatos de cirar o vinculo do código com os registros do banco de dados, então teremos que criar um Adapter, e ela será criada apartir da função: Public Function GetDataAdapter(ByRef cn As IDbConnection, ByVal Sql As String) As IDbDataAdapter Dim leitor As IDbDataAdapter = Nothing Dim cnn As OleDb.OleDbConnection cnn = CType(cn, OleDb.OleDbConnection) Dim adapter = New OleDb.OleDbDataAdapter(Sql, cnn) leitor = adapter Dim cnn As SqlClient.SqlConnection
cnn = CType(cn, SqlClient.SqlConnection) Dim adapter = New SqlClient.SqlDataAdapter(Sql, cnn) leitor = adapter Dim cnn As Odbc.OdbcConnection cnn = CType(cn, Odbc.OdbcConnection) Dim adapter = New Odbc.OdbcDataAdapter(Sql, cnn) leitor = adapter Return leitor Será muito util uma funçao que execute e capture um comando, e elas serão exibida a seguir: Public Function GetCommand(ByVal cn As IDbConnection, ByVal Sql As String) As System.Data.IDataReader Dim comando = Nothing comando = New OleDb.OleDbCommand comando = New SqlClient.SqlCommand comando = New Odbc.OdbcCommand comando.commandtext = Sql comando.connection = cn Dim leitor As IDataReader leitor = comando.executereader() Return leitor Public Function ExecuteCommand(ByVal cn As IDbConnection, ByVal sql As String) As Boolean Try Dim comando = Nothing comando = New OleDb.OleDbCommand comando = New SqlClient.SqlCommand comando = New Odbc.OdbcCommand comando.commandtext = sql comando.connection = cn comando.executenonquery() Return True Catch ex As Exception
Msgbox ("Ocorreu um erro: " & ex.message) MsgBox(sql) Return False End Try Return False Agora criamos algumas propriedades internas: Public Property ConnectionType() As String Get Return VARConectionType End Get Set(ByVal value As String) VARConectionType = value End Set End Property Public Property StringDeConexao() As String Get Return stroledbconn Return strmsdeconn Return strodbcconn Return strconn End Get Set(ByVal value As String) strconn = StringDeConexao End Set End Property End Module O código completo é exibido a seguir: Imports System Imports System.Data.Common Imports System.Data.OleDb Imports System.Data.Odbc Imports System.Data.SqlClient Imports System.Data.SqlTypes Public Module conexao
Private strodbcconn As String = "Driver={Microsoft Access Driver (*.mdb)};dbq=c:\neoartvision\neosis Cobrança\DATA\NeoSisDat.mdb;Uid=Admin;Pwd=" Private strconn As String = "Provider=SQLNCLI.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=NeoSisDat;Data Source=apserver\mssql" Private stroledbconn As String = "Provider=SQLNCLI.1;Integrated Security=SSPI;Persist Security Info=True;Passwort=123456;User ID=neoart;Initial Catalog=NeoSisDat;Data Source=vmserver\mssql" Private strmsdeconn As String = "Persist Security Info=True;User ID=neoart;Password=123456;Initial Catalog=NeoCred;Data Source=APSERVER" Private VARConectionType As String = "MSDE Public Function GetConnection() As System.Data.IDbConnection Return New System.Data.OleDb.OleDbConnection(StringDeConexao) Return New System.Data.SqlClient.SqlConnection(StringDeConexao) Return New System.Data.Odbc.OdbcConnection(StringDeConexao) Return Nothing Public Function GetDataAdapter(ByRef cn As IDbConnection, ByVal Sql As String) As IDbDataAdapter Dim leitor As IDbDataAdapter = Nothing Dim cnn As OleDb.OleDbConnection cnn = CType(cn, OleDb.OleDbConnection) Dim adapter = New OleDb.OleDbDataAdapter(Sql, cnn) leitor = adapter Dim cnn As SqlClient.SqlConnection cnn = CType(cn, SqlClient.SqlConnection) Dim adapter = New SqlClient.SqlDataAdapter(Sql, cnn) leitor = adapter Dim cnn As Odbc.OdbcConnection cnn = CType(cn, Odbc.OdbcConnection) Dim adapter = New Odbc.OdbcDataAdapter(Sql, cnn) leitor = adapter Return leitor
Public Function GetCommand(ByVal cn As IDbConnection, ByVal Sql As String) As System.Data.IDataReader Dim comando = Nothing comando = New OleDb.OleDbCommand comando = New SqlClient.SqlCommand comando = New Odbc.OdbcCommand comando.commandtext = Sql comando.connection = cn Dim leitor As IDataReader leitor = comando.executereader() Return leitor Public Function ExecuteCommand(ByVal cn As IDbConnection, ByVal sql As String) As Boolean Try Dim comando = Nothing comando = New OleDb.OleDbCommand comando = New SqlClient.SqlCommand comando = New Odbc.OdbcCommand comando.commandtext = sql comando.connection = cn comando.executenonquery() Return True Catch ex As Exception Msgbox ("Ocorreu um erro: " & ex.message) MsgBox(sql) Return False End Try Return False Public Property ConnectionType() As String Get Return VARConectionType End Get Set(ByVal value As String) VARConectionType = value End Set End Property Public Property StringDeConexao() As String Get Return stroledbconn
Return strmsdeconn Return strodbcconn Return strconn End Get Set(ByVal value As String) strconn = StringDeConexao End Set End Property End Module Como utilizar isto no meu programa? No seu formulário, adicione os namespaces novamente: Imports System Imports System.Data.Common Imports System.Data.OleDb Imports System.Data.SqlClient Imports System.Data.SqlTypes Crie os seguitne sbotoes: 1. Novo 2. Salvar 3. Abrir 4. Deletar
No botão Abrir coloque o seguinte código If ID = 0 Then Id = inputbox ( Informe o ID do usuario ) Using cn As System.Data.IDbConnection = Conexao.GetConnection Try cn.open() Using leitor As IDataReader = Conexao.GetCommand(cn, "Select * from Usuarios where ID = " & ID) While leitor.read() ID = (leitor.item(0)) Nome = (leitor.item(1)) Bairro = (leitor.item(2)) Celular = (leitor.item(3)) Cep = (leitor.item(4)) Cidade = (leitor.item(5)) CPF = (leitor.item(6)) Endereco = (leitor.item(7)) Login = (leitor.item(8)) Numero = (leitor.item(9)) Orgao = (leitor.item(10)) Rg = (leitor.item(11)) Senha = Criptografia.Crypt((leitor.Item(12))) Telefone = (leitor.item(13)) UF = (leitor.item(14)) Complemento = (leitor.item(15)) TelefoneDDD = (leitor.item(16)) CelularDDD = (leitor.item(17)) GrupoAcionamento = (leitor.item(18)) Tipo = (leitor.item(19)) End While leitor.close() End Using Catch ex As Exception ERRO = ex.message Finally End Try End Using No botão Salvar coloque o seguinte codigo:
Using cn As System.Data.IDbConnection = Conexao.GetConnection cn.open() If ID = 0 Then Try Dim CommandText As String = "Insert into Usuarios (Nome,Bairro,Cel,Cep,Cidade,CPF,Endereco,Login,Numero,Orgao,Rg,Senha,T el,uf,complemento, Tel_DDD, Cel_DDD, GrupoAcionamento, tipo) Values ('" & _ Nome & "','" & _ Bairro & "','" & _ Celular & "','" & _ Cep & "','" & _ Cidade & "'," & _ CPF & ",'" & _ Endereco & "','" & _ Login & "','" & _ Numero & "','" & _ Orgao & "'," & _ Rg & ",'" & _ Criptografia.Crypt(Senha) & "','" & _ Telefone & "','" & _ UF & "','" & _ Complemento & "','" & _ TelefoneDDD & "','" & _ CelularDDD & "','" & _ GrupoAcionamento & "','" & _ Tipo & "'" & _ ")" sucesso = Conexao.ExecuteCommand(cn, CommandText) Catch ex As Exception ERRO = ex.message End Try Else Try Dim CommandText As String = "update Usuarios set Nome ='" & _ Nome & "',Bairro ='" & _ Bairro & "',Cel ='" & _ Celular & "',Cep ='" & _ Cep & "',Cidade ='" & _ Cidade & "',CPF=" & _ CPF & ",Endereco='" & _ Endereco & "',Login='" & _ Login & "',Numero='" & _ Numero & "',Orgao='" & _ Orgao & "',Rg=" & _ Rg & ",Senha='" & _ Criptografia.Crypt(Senha) & "',Tel='" & _ Telefone & "',Complemento='" & _ Complemento & "',Tel_DDD='" & _ TelefoneDDD & "',Cel_DDD='" & _ CelularDDD & "',GrupoAcionamento='" & _ GrupoAcionamento & "',Tipo='" & _
Tipo & "',UF='" & _ UF & "'" & _ " where ID = " & ID sucesso = Conexao.ExecuteCommand(cn, CommandText) Catch ex As Exception ERRO = ex.message End Try End Using No botão Delete adiciono o codigo: Using cn As System.Data.IDbConnection = Conexao.GetConnection Try cn.open() Dim CommandText As String = "Delete from Usuarios where ID = " & ID Conexao.ExecuteCommand(cn, CommandText) Catch ex As Exception ERRO = ex.message Finally End Try End Using No botão Novo adicione o código ID = 0 Pronto, estamos com uma conexão Generica que pode ser usada para qualquer banco de dados, para outros provedores não informado aqui, necessita apenas da implementação do código.
Outra implementação que crie foi a conversão de data. Exemplo, se um código esta pronto para Acces, quando trocado para SQLexpress por exemplo, quando informada a data no formato DD/MM/AAAA há erro, então pode ser adicionado uma função que conforme o banco de dados ele converta a data conforme o suportado pelo banco: Eu iniciei a implementação da sequinte forma, mas poderá ser ajustada por você para suportar outras versoes: Public Function DataToSQLData(ByVal OldData As String) As String Dim data As Date = OldData Return data.year & "/" & data.month & "/" & data.day