You are on page 1of 8

Gambastieneestructuradoelaccesoabdmediantedrivers.Estossonmdulosdecdigoescritospor diversosprogramadoresespecficamenteparacomunicarseconunabddeterminada,loquepermite accederadistintasbasesutilizandoenmismocdigo.Bastaconespecificareltipodebdautilizar,yel restodelcdigofuncionar,posiblementesinmodificaciones,conindependenciadelabdutilizada. Gambaspuedemanejarvariostiposdebd.Disponeenestemomentode3driversespecficos:SQLite, MysqlyPostgres.AdemscuentaconundriverODBC,elcualesunestndarparacomunicar aplicacionesconbd.Porlotanto,podemosaccederconGambasacualquierbasequesoportedicho estndar.Estopermiteentrar,porejemplo,abasesdeMSSQLServeroFirebird. Alahoradeelegirundriveruotro,tendremospresentequelosdriversespecficosestnoptimizadosy ofrecenunamayorvelocidaddetransferenciadedatos.Solocuandonodispongamosdeunoespecfico, usaremoselODBC. HablandodelaestructuradeGambas,cualquieraplicacinqueuseestacaracterstica,necesitarel componentegb.dbcomodependencia.Losdriversparacadasistemadebdsontambincomponentes, peroelprogramadornohademarcarloscomodependencias.Unavezqueindiquemosaquesistema nosvamosaconectar,elinterpretedegambastratardecargareldriverespecfico.

Estoscomponentesson: gb.db.sqlite gb.db.sqlite3 gb.db.mysql gb.db.postgres gb.db.odbc CreacindeBD Abrimosunproyectonuevoengambas,vamosalmenherramientasyseleccionamosGestordeBD. Tambinpodemosejecutarlodirectamentedesdeconsola,conelcomandogambasdatabasemanager. Despusdeestonospreguntarunacontrasea,dichacontraseaseempleaparaalmacenarencriptados losdatosdeusuarioycontraseasquedeseemosgestionardesdeesteprograma,paraevitarqueotro usuariopuedaleerlosconfacilidadconsultandolosficherosdelentornogrficodegambas.La contraseadeberteneralmenos8caracteresysepreguntarcadavezqueseinicieelprograma,para desencriptarcontraseasyaalmacenadasensesionesprevias. AcontinuacinapareceelgestordeBDquealprincipioestavaco,yaquenohemosconfigurado ningunaconexin. Paragenerarunanuevaconexin,vamosalmenServidoryseleccionamoslaopcinNuevoservidor. ElprimerdatoTipo,serefierealdriverqueemplearemos:splite,mysql,posgresuodbc.Hostesel nombredelequipoodireccinIPdonderesideelservidordeBD(puedeserlocalhost).Como excepcin,paralasconexionessqlite,elhostnoserotracosaquelacarpetadondeseencuentran alojadaslasBD,esdecir,unarutaabsoluta(/home/usuario/bases). LosltimosdatossonelnombredeUsuarioylaContraseaparaaccederalsistemadeBD,que determinanlosdistintosprivilegiosdelusuario.

ParaconectarsealservidordeBdqueseacabadecrear,dedobleclicsobreelservidoroclickderecho ylaopcinAbrir.Unavezconectados,sepuedenhacerlassiguientesacciones: 1. Crearusuario:tienesentidositrabajamossobreunsistemaservidordeBDytenemospermisos deadministracinsobreelservidor,elusodeestaopcinestrivial;yaquesolosepreguntael nombredelusuario,ysucontraseaparaagregarlo 2. Crearbase:estaopcinnosayudaracrearunabd,nospreguntarelnombredelabasede datosacrearypulsamosOK. Ahorayatenemosunabasededatosvaca,dondesehandecreardistintastablas. CreacindeTablas Primerohayqueabrirelservidorqueseutilizar,dandodobleclicsobrelyacontinuacinclic derechoparaqueseabraelmencontextual,elcualtienelassiguientesopciones:Crear,creartabla, peticinSQL,importararchivoCSV,crearcdigogambas,utilizarcodificacin(utf8),Mostrartablas delsistema. ConlaopcinCreartabla,segenerarlatabladelabasededatosdeseada,indicandoelnombredela tabla,yeltipo.EltipodetablaseusausualmenteconbasesdedatosdeMySQL,dondesepueden indicarvariostiposdetablasoptimizadasparaunauotratareasconcreta:BDB,Heap,InnoDB,ISAM, MERGE,MyISAM.Sinembargodejarlosvalorespordefectoesbuenaidea. Tarea:investigarparaquesirvecadatipodetabla. Unavezcreadalatablaaparecerdelladoderechodelaventanadelgestorlaestructuraactualdela tabla(actual),paraqueagreguelainformacincorrespondientealoscamposytiposdecamposque compondrnalatabla. ComencemosconlapestaaCAMPO,Ahsedefinenlosatributos,sutipoylongitud.Pordefault apareceuncampollamadoidqueaparececomollaveprimariadelatabla,siesdeutilidadlo podemosdejar,ocomplementarconlosbotonesdemanipulacinqueaparecenenlapartesuperiorde laventana. Tarea:InvestigarquetiposdellavesaceptaMySQL Nota:EldatolongitudseaplicasoloacamposdetipoStringyserefierealnumerodecaracteresquese puedenalmacenar.Convieneajustarlomsposibleelvalorparanohacercreceralabasededatosen demasay,portanto,hacermslentaslasbsquedasymodificacionesposteriores. Gambasrealizaunaabstraccindelostiposdedatos,permitiendoelegirentreunosmuyconcretos: Boolean,Integer,Float,StringyFecha.Estostiposabstraenlosdelapropiabasededatos. Tarea:InvestigarquetiposdedatostieneMySQL Nota:Losnombresdetablasycamposnodebenllevaracentos,nitildesnicaracteresespeciales,nose debeusarotracosaquecaracteresdelalfabetoinglsynmeros. Unavescreadalatablapodemoseditarloscampos,aadiroquitar,siguiendoelmismoprocedimiento. Tarea:Paraquesirvenlosndicesenlasbasesdedatos???

Existenotrasdospestaasquenosservirnparamanipular,tantolaestructura,comoparalosdatos; ndicesyDatos.Enlapestaandicespondremosgenerarunndiceparalatabla,recordemosqueun ndicepuedeestarformadoporunoodoscampos.EnlapestaaDatospodremosinsertaroagregar, eliminarregistrosalatabla. GambaspermitetambingenerarsentenciasSQLpararealizarconsultasalaBD,conlosdatos almacenadosenella. ElobjetoConnectiondisponedeunaseriedepropiedadesparadeterminareltipodesistemadebd,la ubicacindelrecurso(puedeserunarutaenelsistemadearchivosounadireccinIP),ylosdatosdel usuarioquedeseaconectarseadichosistema.Estaclase,juntoconlaclaseDatabase,aportanla informacinnecesariasobrenuestrabd.LaclaseUserperfilanuestrousuarioy,portanto,nuestros permisosdeacceso. Lainformacindeunabasededatossealmacenaendiversastablas.Cadatablasepuedeimaginar comounarejillabidimensional,alestilodeunahojadeclculo.Engambas,elcomponentegb.db aportaunaclaseTable,quedefinelaestructuradeunatabla,ylaclaseFieldquedeterminalas caractersticasdeuncampodeunatabla. CuandoserealizaunapeticinSQLalabasededatos(consulta)losdatosregresadossepresentan igual,enformadetabla.LosobjetosdelaclaseResultproporcionanelaccesoadichosregistrosy camposdeinformacin. LaclaseResultFieldessimilaraField,peroenestecasonoproporcionainformacinsobreuncampo deunatabladeunabd,sinosobreuncampodeunconjuntoderegistrosprocedentesdeunaconsulta. CONECTANDOSEPORCDIGO Genereunformularioagregandounobjetocolumnview,quesellameTabla.Ahoraescribiremosuna funcinqueseconectealservidordeBD.
PrivatehConnasConnection PrivatefunctionconectarseBase()asBoolean Ifhconn<>nullthenreturnfalse hconn=newconnection hconn=newconnection hconn.host=NOMBREMAQUINA hconn.name=NOMBREBASE hconn.Type=SMBD hConn.login= hConn.passwd= tryhconn.open() iferrorthen hconn=null Message.error(Erroralconectarconlabase) returntrue endif returnfalse end

Elcdigoconllevaestospasos: 1. Siyahayunaconexin(sielobjetohConnesnulo),retornamosinmediatamenteindicandoque yahayunaconexinFALSE,esestaformapodremosllamarsistemticamenteaestafuncin desdevariospuntossinpreocuparsedesiyaexisteono. 2. CreamoselobjetoConnection,queenprincipionoestconectadoaningunabase,y proporcionamoslainformacinnecesariaparaconectar;llenarlapropiedadHost,IP,elnombre deBDyporultimoelSMBDalqueseconectar.EnelcasodeMySQLseagregarnLoginy Password. 3. Despusseabrirlaconexin,sinoesposible,sedisparaunerror,quesecapturaconlaorden TRY. 4. Sisehaproducidounerror,hacemosnuladenuevolaconexinfallidayretornamosconel valordeerror,quesegnhemosdecidido,esTRUE. 5. Siporelcontrario,huboxito,retornamoselvalorcorrespondiente(FALSE). Acontinuacinsecrearlafuncinquecerrarlaconexin.
PrivateSUBCerraConexion() ifhconn=nullthenreturn hconn.close() hconn=null end

CONSULTARDATOS Alabrirseelformulario,abriremoslaconexin,leeremoslosdatosdisponiblesdesdelaBD almacenadaenelSMBD,losrepresentaremosennuestrocontrolTablaycerraremoslaconexin.Dela siguientemanera:


Publicsubform_open() dimhresulasResult dimclaveasstring tabla.clear() IfconnectarBAse()thenreturn tabla.columns.count=5 Tabla.Columns[0].text=ENCABEZADO1 Tabla.Columns[1].text=ENCABEZADO2 Tabla.Columns[2].text=ENCABEZADO3 Tabla.Columns[3].text=ENCABEZADO4 Tabla.Columns[4].text=ENCABEZADO5 hresul=hconn.Exec(Select*fromNOMBRETABLA) Dowhilehresult.Available Clave=hresul[ATRIBUTO1] Tabla.add(clave,clave) Tabla[clave][1]=hresul[ATRIBUTO2] Tabla[clave][2]=hresul[ATRIBUTO3] Tabla[clave][3]=hresul[ATRIBUTO4] Tabla[clave][4]=hresul[ATRIBUTO5] hresul.MoveNext() Loop CerrarConexion() End

Sedefinen5columnasenelcontroldetabla,poneeltituloalosencabezadosdecolumnayprocedea rellenarlosregistros,consultandoprimerolosdatosdelatabla(select...)seempleaelmtodoExecdel objetohconn,alcualsepasacomoparmetrolaconsultaSQLydevuelveunobjetodelaclaseResult, quecontienecadaunodelosregistrosprovenientesdelaconsulta. ElobjetoResulttieneunpunterointernoqueencadamomentoapuntaaunodelosregistros.Enel estadoinicialapuntaalprimerregistro,siesquehayalguno.Esteobjetodisponedeunaseriede mtodosparamoverelpuntero.MoveNext(eldelejemplo)lomuevealsiguientepuntero,siexiste; MovePrevious,alanterior;MoveFirst,alprimero;yMoveLast,alltimo.MoveTopodemosespecificar unregistroconcretoalquedesplazamos. Cuandoestamossituadosenunregistro,Resultnospermiteobtenereldatocorrespondienteaun campo,indicandoelnombredelcampocomosielobjetofueseunArray:ennuestroejemplo, hresul[autor]nosdevuelveelvalordelcampoautorenelregistroactual. Sicomoresultadodeunmovimientodelpunterohemossobrepasadoelultimoregistrooestamosantes delprimero,lapropiedadAvailabletomaelvalordeFalse,mientrasquesiencontramosapuntandoa unregistro,AvailabletomaelvalordeTrue.Igualmente,sinohayregistrosresultantesdelaconsulta, AvailablevaldrFalse. Mientraslapropiedadavailableseatrue,tomamoscomoclaveelvalordelcampotitulo,aadimos unalneaennuestratablaidentificadaporesaclave,ycuyotexto(primeracolumna)esdichaclave. Rellenamoselrestodeloscamposconlosvaloresprovenientesdelobjetohresult,ynosmovemosal siguienteregistro.Trassalirdelbucle,cerramoslaconexinyabandonamoslafuncin. Comoultimoyantesdeejecutar,ponemoslapropiedadSorteddelcontrolColumnViewatrue,de modoqueelusuario,alpulsarsobreunencabezadodecolumna,puedaordenarellistadoporelcampo queprefiera.Puestoquecadaregistroenellistadoestidentificadoporlamismaclavequetieneenla tabla,posterioresoperacionesdeseleccin/modificacinporpartedelusuario,nosevenafectadaspor elordenderepresentacin. BORRARREGISTROS

Publicsubtabla_KeyRelease() ifkey.code=key.deletethen iftabla.current=nullthenreturn iftabla.current.selected=falsethenreturn ifconnectarBase()thenreturn tryhconn.exec(deletefromNOMBRETABLAwhereATRIBUTO=&1,tabla.current.key) iferrorthen Message.error(Imposibleborrarelregistro) else tabla.current.delete() endif cerrarconexion() endif end

AprovechamoseleventoKey_ReleasedelcontrolTabla.SilateclapulsadaesDeloSupr,primero comprobamossiexistealgnelementoactualenlatabla;sinoess,salimos.Sielelementoactualno estseleccionado,tambinsalimos.Porotrolado,tratamosdeabrirlaconexin,ysihayxito, ejecutamosunainstruccinSQLparaborrarunregistrocuyaclavecoincidaconladelregistrode nuestrocontrolColumnView.Siseproduceunerror(porejemplo,unabaseesololectura),seinforma, encasocontrarioseborratambinelregistrodelcontrolparareflejarelcambio.Cerramoslaconexin ysalimosdelafuncin. EnestecasousamosunainstruccinSQLdiferente,setienendosparmetros,elprimeroespartedela consultayelsegundocontieneelelementoconcretoalquenosreferimos. ElmtodoExecadmiteunnumerovariabledeparmetros,yalahoradetratarlasentenciaSQL, gambassustituyelosindicaresdeparmetros(&1,&2,&3...)porelparmetroquecorrespondeenorden (&1eselprimerparmetroextra,&2elsegundo....)Adems,formateaeldatosegnsenecesite(por ejemplo,esteparmetrocorrespondeaundatodetipoString,queenlasintaxisdeSqliterequiere comillas).Estoesmuytilparatrabajarcondatosdetipofecha/hora,cadenasdetextoynmeroscon decimales,yaquelasintaxispuedevariasdeuntipodeBDaotras,einclusoconlamismabasesegn losparmetrosregionales(formatodefecha,usarcomaopuntoparadecimales,etc).Conestesistema, pondremossimplementeundatodetipocadena,booleano,fechaonumeroygambasseencargarde darelformatoadecuado. AGREGARREGISTROS GenerarunformulariollamadoFdatacon5etiquetasy5cajasdetexto,dosbotones(ok,cancelar). Esteformulariorecibirunareferenciaalaconexinconlabd,portantodispondrdeunareferenciaa unObjetoConnection.Porellodeberemosescribiralprincipiodelcdigolosiguiente: PRIVATEhConnASConnection Asmismo,dispondrdelmtodoRunNewconelquelellamaremosdesdeelformularioprincipal, pasandocomoparmetronuestraconexinalabase,yquenosmostrarelformulariodeformamodal, alaesperadelaintroduccindedatosporpartedelusuario.
PUBLICSUBRunNew(DataASConnection) hConn=Data Me.ShowModal() End

ElcdigotomaenhConnlareferenciaalobjetoConnectionquelepasemos,ylomuestra.Encuantoal botndecancelacin,bastaconindicaralformularioquecierre:
PUBLICSUBBotonCancelar_click() Me.Close() End

EnelbotnAceptar,realizaremoslaoperacindealtadeunnuevoregistro,utilizandolainstruccin SQLInsertinto...

PUBLICSUBbotonAceptar_click() TryhConn.Exec(insertintodatosvalues(&1,&2,&3,&4,&5),texttitulo.text, textautor.text,Cdate(textFecha),Cfloat(textprecio.text),textdescripcion.text) Me.close() catch Message.error(imposibleintroducirlosdatossolicitados) end

IndicamosalobjetoConnectionqueejecutelasentenciaSQLparainsertar. Paraevitarproblemasdeformateoseguimosempleandolosparmetrosadicionales,comoenel ejemploanterior.Losdatostitulo,descripcinyautorsepasandirectamente,alserdatostipotexto. EldatoPrecioyfechaseconviertenasucorrespondiente(Cfloat,Cdate). Acoplaremosahoraelformularioprincipalalcreadoparadardealtaaregistros.Sedebertenerun botnllamadoAgregar.Estebotntratardeconectarsealabd,peronossalimossinolologramos.A continuacinllamamosalmtodoRunNewdeFdata.Puestoquesemuestradeformamodal,elcdigo deesteformularioquedaaqudetenidohastaqueelusuariodunaltaocierreelformulario. Trasesto,ydenuevoenlafuncin,cerramoslaconexinyllamamosalmtodoform_open(),que, comorecordamos,seencargabaderepresentarlosdatosenlatabla,parareflejaraselaltadadaporel usuario.
PUBLICSUBBotonNuevo_clicl() ifconectarbase()thenreturn Fdata.RunNew(hconn) CerrarConexion() Form_Open() end

__________________________________________________________________________________ CargarlosdatosenelGridView,desdeunatablaProductosenestemomentosoloimportael funcionamientodelGridViewasquedejamosdeladomomentneamentelaconexinqueyaesta implcita.


PUBLICSUBForm_Open() DIMfilPASIntegerContadordefilas DIMcolPASIntegerContadordecolumnas resProductosesunobjetoResulparaalmacenarelresultadodelaconsulta conexesunObjetodetipoConnectionparalasconexionaBDenGambas ElmetodoExec()ejecutaunasentenciaSQL resProductos=conex.Exec(select*fromProductos) Ponemoselnumerodecolumnasados gvProductos.Columns.Count=2 NrodefilasdeacuerdoalacantidaddeproductosquetenemosenlaBD gvProductos.Rows.Count=resProductos.Count Asignamoslacabeceradelatabla gvProductos.Columns[0].Text=DescripciondelProducto gvProductos.Columns[0].Width=375 gvProductos.Columns[1].Text=Precio

gvProductos.Columns[1].Width=50 JalamoslosdatosdesdeelObjetoResultresProductoshaciaelGridView MientrashayanfilasenelResult DOWHILEresProductos.Available gvProductos[filP,colP].Text=resProductos["descripcion"] colP=1 gvProductos[filP,colP].Text=$&resProductos["precio"] colP=0 filP=filP+1 PasamosalasiguientefiladelObjetoResult resProductos.MoveNext() LOOP END

AhoracomohacemosparaeliminarunproductodelGridViewsipresionamoslateclaSuprimir PUBLICSUBgvProductos_KeyRelease() IFKey.Code=Key.DeleteTHENComprobamossilateclaesSuprimir IFgvProductos.Current=NULLTHENRETURN SELECTMessage.Question(Deseaeliminaresteproducto,Si,No,Ayuda) CASE1 TRYconex.Exec(DeletefromProductoswheredescripcion=&1, gvProductos.Current.Text) IFERRORTHEN Message.Error(Imposibleborrarelregistro) ELSE gvProductos.Rows.Remove(gvProductos.Row) ENDIF CASE2 CASE3 ENDSELECT ENDIF END

You might also like