Vous êtes sur la page 1sur 11

Utilizacindelmodoconectado

Enestecaptulo,vamosatratardelasoperacionesquepuedenserejecutadasenunabasededatosalutilizarel
modo conectado. Ciertas nociones estudiadas en este captulo sern tiles para el funcionamiento en modo
desconectado. Para probar las distintas funcionalidades estudiadas en este captulo, utilizaremos un servidor SQL
Server2010.LabasededatosutilizadaserlabaseNorthwindquesecreapordefectocuandoseinstalaelservidor.
Unapartedelaestructuradelabaseestdisponibleenelesquemasiguiente:

1.Conexinaunabasededatos
Parapodertrabajarconunservidordebasededatos,unaaplicacindebeestablecerunaconexinderedconel
servidor. La clase SqlConnection es capaz de gestionar una conexin hacia un servidor SQL Server versin 7.0 o
posterior.Comoparacualquierobjeto,enprimerlugardebemosdeclararunavariable.

Dim ctn As System.Data.SqlClient.SqlConnection

Luego,debemoscrearlainstanciadelaclaseeinicializarlainvocandounconstructor.Lainicializacinvaaconsistir
esencialmenteenindicarlosparmetrosutilizadosparaestablecerlaconexinconelservidor.Estosparmetrosse
definen en forma de una cadena de caracteres. Pueden ser indicados durante la llamada al constructor o
modificadosporlapropiedadConnectionString.

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

- 1-

a.Cadenadeconexin
El formato estndar de una cadena de conexin est constituido por una serie de pares palabra clave/valor,
separadasporpuntosycomas.Elsigno=seusaparalaasignacindeunvaloraunapalabraclave.Elanlisisde
lacadenaseefectadurantelaasignacindelacadenaalapropiedadConnectionString.Losvaloresasociadosa
laspalabrasclaveseextraenyseasignanalasdistintaspropiedadesdelaconexin.Siseencuentraunerrorde
sintaxis,segeneraunaexcepcininmediatamenteynosemodificaningunapropiedad.Porelcontrario,solose
podr controlar algunas propiedades durante la apertura de la conexin. En este momento se activar una
excepcinsilacadenadeconexincontieneunerror.solosepuedemodificarlacadenadeconexinsilaconexin
estcerrada.Estassonlaspalabrasclavesexistentesparaunacadenadeconexin:
ConnectTimeout
Duracinensegundosdurantelacuallaaplicacinesperarunarespuestadelservidorasupeticin
deconexin.Pasadoesteplazo,seactivaunaexcepcin.
DataSource
Nombreodireccindereddelservidorhaciaelqueseestablecelaconexin.Elnmerodelpuertose
puedeespecificardespusdelnombreodeladireccindered.Sinoestindicado,elnmerode
puertoesiguala1433.
InitialCatalog
Nombredelabasededatosenlaquesedebeefectuarlaconexin.
IntegratedSecurity
Siestevalorsecolocaenfalse,sedebefacilitarunnombredeusuarioyunacontraseaenla
cadenadeconexin.Encasocontrario,seutilizalacuentaWindowsdelusuarioparala
autenticacin.
PersistSecurityInfo
Siseposicionaestevalorentrue,elnombredelusuarioysucontraseasonaccesiblesporla
conexin.Porrazonesdeseguridad,sedebecolocarestevalorenfalse.Dehecho,esassinoindica
nadaenlacadenadeconexin.
Pwd
ContraseaasociadaalacuentaSQLServerutilizadaparalaconexin.Sinoexistecontrasea
asociadaaunacuenta,sepuedeomitirestainformacinenlacadenadeconexin.
UserID
NombredelacuentaSQLServerutilizadaparalaconexin.
ConnectionLifeTime
Indicaladuracindeunaconexinenunpooldeconexiones.Unvalorigualaceroindicauna
duracinilimitada.

- 2-

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

ConnectionReset
Indicasilaconexinesreinicializadacuandovuelveaentrarenelpool.
MaxPoolSize
Nmeromximodeconexionesenelpool.
MinPoolSize
Nmeromnimodeconexionesenelpool.
Pooling
Indicasilaconexinsepuedeextraerdeunpooldeconexiones.
Unacadenadeconexinadoptalasiguienteformamnima:

ctn.ConnectionString = "Data Source=Minerve;Initial Catalog=Northwind;


Integrated
Security=true"

b.Pooldeconexiones
Lospoolsdeconexionespermitenmejorarlasprestacionesdeunaaplicacinalevitarlacreacindeconexiones
adicionales. Cuando una conexin est abierta, se crea un pool de conexiones que se basa en un algoritmo
basado,asuvez,enlacadenadeconexin.Ascadapoolestasociadoaunacadenadeconexinparticular.Si
se abre una nueva conexin y no hay pool que corresponda exactamente a su cadena de conexin, se crea un
nuevopool.Lospoolsdeconexionesascreadosexistirnhastaelfinaldelaaplicacin.Cuandosecreaunpool,
sepuedencrearotrasconexionesautomticamenteparasatisfacerelvalorMin Pool Sizeindicadoenlacadena
de conexin. Se podrn aadir otras conexiones al pool hasta alcanzar el valor Max Pool Size de la cadena de
conexin.Cuandoserequiereunaconexin,sepuedeobtenerapartirdeunpooldeconexiones(siexisteuno
quecorrespondeexactamentealascaractersticasdelaconexinrequerida).Porsupuesto,esnecesarioqueel
poolcontengaunadisponibleyactiva.
Sisealcanzaelnmeromximodeconexionesenelpool,lapeticinseponeenlacolahastaqueunaconexin
estdenuevodisponible.Unaconexinsevuelveaponeradisposicindelpooldurantesucierreodurantela
llamada del mtodoDispose en la conexin. Por esta razn, se recomienda cerrar explcitamente las conexiones
cuandoyanoseutilizanenlaaplicacin.Seretiranlasconexionesdelpoolcuandoestedetectaquelaconexin
nohasidoutilizadaduranteunciertotiempo,indicadoporelvalorConnectionLifeTimedelacadenadeconexin.
Tambinseretiranlasconexionesdelpoolsiestedetectaquelaconexinconelservidorhasidointerrumpida.

c.Eventosdeconexin
LaclaseSQLConnectionproponedoseventosquelepermitenseravisadocuandoelestadodelaconexincambia
ocuandoelservidorenvaunmensajedeinformacin.EleventoStateChangedseactivacuandocambiaelestado
delaconexin.ElgestordeesteeventorecibeunparmetrodetipoStateChangeEventArg,quepermiteobtener
conlapropiedadCurrentStateelestadoactualdelaconexin,yconlapropiedadOriginalState,elestadodela
conexin antes de la desactivacin del evento. Para probar el valor de estas dos propiedades, puede utilizar la
enumeracinConnectionState.

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

- 3-

Elevento InfoMessage se activa cuando el servidor le informa de una situacin anormal, pero que no justifica la
activacin de una excepcin (gravedad del mensaje inferior a 10). El gestor de eventos asociado recibe un
parmetro de tipo InfoMessageEventArgs. Por la propiedad Errors de este parmetro, tiene acceso a objetos
SqlErrors que corresponden a las informaciones enviadas por el servidor. El siguiente cdigo muestra en la
consolalosmensajesdeinformacinqueprovienendelservidor.

Private Sub ctn_InfoMessage(ByVal sender As Object, ByVal e As System.Data.


SqlClient.SqlInfoMessageEventArgs) Handles ctn.InfoMessage
Dim info As SqlClient.SqlError
For Each info In e.Errors
Console.WriteLine(info.Message)
Next
End Sub

2.Ejecucindeuncomando
Despusdehaberestablecidounaconexinhaciaunservidordebasededatos,puedetransmitirleinstrucciones
SQL.SeutilizalaclaseSqlCommandparapediralservidorlaejecucindeuncomandoSQL.Estaclasecontienevarios
mtodosquepermitenlaejecucindediferentestiposdeconsultasSQL.LaclaseSqlCommandpuedeinstanciarsede
maneraclsica,utilizandounodesusconstructores,osepuedeobtenerunainstanciaporelmtodoCreateCommand
delaconexin.

a.Creacindeuncomando
LaprimeraposibilidadparacrearunainstanciadeSqlCommandconsisteenutilizarunodelosconstructoresdela
clase. El uso del constructor por defecto le obliga a utilizar diferentes propiedades para facilitar la informacin
relativaalainstruccinSQLquesevaaejecutar.
LapropiedadCommandTextcontieneeltextodelainstruccinSQLquesevaaejecutar.LapropiedadConnection
debehacerreferenciaaunaconexinvlidahaciaelservidordebasededatos.Elsiguientecdigoresumeestas
diferentesoperaciones:

Dim cmd As SqlCommand


cmd = New SqlCommand
cmd.Connection = ctn
cmd.CommandText = " SELECT * FROM Products"

Lasegundasolucinconsisteenutilizarunconstructorsobrecargadoqueaceptecomoparmetroslainstruccin
SQLenformadecadenadecaracteresylaconexinutilizadaporestaSqlCommand.Assepuederesumirelcdigo
anteriorconlasiguientelnea:

- 4-

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

Dim cmd As new SqlCommand( " SELECT * FROM Products",ctn)

LatercerasolucinconsisteenutilizarelmtodoCreateCommanddelaconexin.Enestecaso,sedebeespecificar
nicamentelainstruccinSQL.

Dim cmd as SqlCommand


cmd = ctn.CreateCommand
cmd.CommandText = " SELECT * FROM Products"

b.Lecturadedatos
Amenudo,lainstruccinSQLdeunSqlCommandseleccionaunconjuntoderegistrosenlabasededatos,oaveces
unvalornicoqueeselresultadodeunclculoefectuadosobrevalorescontenidosenlabase.Unainstruccin
SQL, que devuelve un conjunto de registros, debe ser ejecutada con el mtodo ExecuteReader. Este mtodo
devuelveunobjetoDataReaderquepermitirdespuslalecturadelainformacinprocedentedelabasededatos.
Silainstruccinsolodevuelveunvalornico,elmtodoExecuteScalarseencargadelaejecucinydevuelvepor
smismoelvalordelabasededatos.
Elsiguientecdigopermitesaberelnmerodepedidospasadosporuncliente:

cmd.CommandText = " select count(orderid) from orders where customerid=FRANK"


Console.WriteLine("el cliente FRANK ha pasado {0} pedidos(s)",
cmd.ExecuteScalar())

Elcasodelasinstruccionesquedevuelvenvariosregistrosesunpocomscomplejo.Despusdehaberejecutado
lainstruccinconelmtodoExecuteReaderydehaberrecuperadoelobjetoDataReader,puedeutilizaresteltimo
para recorrer los resultados devueltos. El mtodoRead de la clase DataReader permite el desplazamiento por el
conjunto de los registros devueltos. Este mtodo devuelve un booleano que indica si queda otro registro. El
desplazamiento solo es posible desde el primero hasta el ltimo registro. Este tipo de desplazamiento se llama
Forward Only. La informacin contenida en el registro actual es accesible con uno de los mtodos Get... de la
claseDataReader.Estosmtodospermitenextraerlosdatosdelregistroyconvertirlosenuntipodedatos.NET.
Existe una versin para cada tipo de datos del Framework .NET. Por supuesto, hace falta que la informacin
presenteenelregistrosepuedaconvertireneltipocorrespondiente.Silaconversinesimposible,seactivauna
excepcin. Los mtodos Get... esperan, como parmetro, el nmero del campo en el que deben recuperar la
informacin.TambinpuedeutilizarlapropiedadpordefectoItemdelDataReader,indicandoelnombredelcampo.
Enestecaso,nohayconversinyelvalordevueltoesdetipoObject.
Elsiguientecdigomuestralalistadetodaslascategorasdeproductosdisponibles:

Imports System.Data.SqlClient
Module TestExecuteReader
Dim cmd As SqlCommand
Dim

ctn As SqlConnection

Dim lector As SqlDataReader


Public Sub main()
ctn = New SqlConnection()
ctn.ConnectionString = "Data Source=localhost;
Initial Catalog=Northwind;Integrated Security=true"

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

- 5-

ctn.Open()
cmd = New SqlCommand
cmd.Connection = ctn
cmd.CommandText = " select * from categories"
lector = cmd.ExecuteReader
Do While lector.Read
Console.WriteLine("nmero de la categora:{0}" & vbTab &
"Descripcin:{1}", lector.GetInt32(0), lector("CategoryName"))
Loop
lector.Close()
ctn.Close()
End Sub
End Module

LautilizacindeunaconexinporpartedeunDataReaderseefectademaneraexclusiva.Paraquelaconexin
estdenuevodisponibleparaotrocomando,debecerrar DataReaderdespusdesuutilizacin.

c.Modificacionesdelosdatos
La modificacin de los datos en una base de datos se efecta principalmente con las instruccionesSQL INSERT,
UPDATE,DELETE. Estas instrucciones no devuelven registros procedentes de la base de datos. Para utilizar estas
instrucciones, debe crear un SqlCommand, y luego pedir la ejecucin de este comando travs del mtodo
ExecuteNonQuery. Este mtodo devuelve el nmero de registros afectados por la ejecucin de la instruccin SQL
contenidaenelSqlCommand.SilapropiedadCommandTextcontienevariasinstruccionesSQL,elvalordevueltoporel
mtodo ExecuteNonQuery corresponde al nmero total de filas afectadas por todas las instrucciones SQL del
SqlCommand.
ElsiguientecdigoaadeunanuevaempresadeentregaenlatablaShippers:

Imports System.Data.SqlClient
Module TestExecuteNonQuery
Dim cmd As SqlCommand
Dim ctn As SqlConnection
Public Sub main()
ctn = New SqlClient.SqlConnection()
ctn.ConnectionString = "Data Source=localhost;
Initial Catalog=Northwind;Integrated Security=true"
ctn.Open()
cmd = New SqlClient.SqlCommand
cmd.Connection = ctn
cmd.CommandText = "Insert into shippers (companyname,phone) values
(DHL,91 123 56 87 43)"
Console.WriteLine("{0} fila(s) aadidas(s) en la tabla",
cmd.ExecuteNonQuery)
ctn.Close()
End Sub
End Module

d.Utilizacindeparmetros
La manipulacin de instrucciones SQL se puede facilitar con la creacin de parmetros permiten construir

- 6-

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

instruccionesSQLgenricasquesepuedenvolverautilizarfcilmente.Elprincipiodefuncionamientoesparecidoa
los procedimientos y funciones de Visual Basic. Una alternativa a la utilizacin de parmetros podra ser la
construccindinmicadeinstruccionesSQLporconcatenacindecadenasdecaracteres.
Acontinuacin,unejemploqueutilizaestatcnicayquepermitelabsquedadeunclienteporsucdigo(luego
veremoscmomejorarestecdigoalutilizarparmetros):

Imports System.Data.SqlClient
Module TestBuscarConcat
Dim cmd As SqlCommand
Dim ctn As SqlConnection
Dim lector As SqlDataReader
Dim codCliente As String
Public Sub main()
ctn = New SqlConnection()
ctn.ConnectionString = "Data Source=localhost;
Initial Catalog=Northwind;Integrated Security=true"
ctn.Open()
cmd = New SqlCommand
cmd.Connection = ctn
Console.Write("introducir el cdigo del cliente buscado:")
codCliente = Console.ReadLine()
cmd.CommandText = " SELECT * from Customers WHERE CustomerID = "
& codCliente & ""
lector = cmd.ExecuteReader
Do While lector.Read
Console.WriteLine("nombre del cliente:{0}", lector("ContactName"))
Loop
lector.Close()
ctn.Close()
Console.ReadLine()
End Sub
End Module

LaparteimportantedeestecdigoseencuentraenelmomentodeasignarunvaloralapropiedadCommandText.
UnainstruccinSQLcorrectasedebeconstruirporlaconcatenacindecadenasdecaracteres.Ennuestrocaso,
esto es relativamente sencillo porque solo hay un valor variable en la instruccin SQL. Si fuera necesario variar
muchosdatos,seraprecisorealizarunagrancantidaddeconcatenaciones.Loserroresclsicosquesecometen
enestasconcatenacionesson:

Olvidarsedeunespacio.

Olvidarsedeloscaracteres"paraenmarcarunvalordeltipocadenadecaracteres.

Unnmerodecarcterimpar.

Todos estos errores tienen el mismo efecto: la creacin de una instruccin SQL invlida que ser rechazada
durantelaejecucinporelservidor.
Lautilizacindelosparmetrossimplificaconsiderablementelaescrituradeestetipodeconsulta.Seutilizanlos
parmetrosparamarcarunaubicacinenunrequerimientodondeestarcolocado,enelmomentodelaejecucin,
unvalorliteralcadenadecaracteresonumrico.Losparmetrospuedensernominalesoannimos.Unparmetro
annimoseintroduceenunaconsultaconelcarcter?.Losparmetrosnominalesseespecificanconelcarcter@
seguidoporelnombredelparmetro.
Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

- 7-

Laconsultadenuestroejemploanteriorpuedeadoptarlasiguienteforma:

cmd.CommandText = " SELECT * from Customers WHERE CustomerID = ?"

cmd.CommandText = " SELECT * from Customers WHERE CustomerID = @Codigo

LaejecucindelSqlCommandfracasaahorasinoseleproporcionanlosvaloresdelosparmetros.

El SqlCommand debe tener una lista de valores utilizados para reemplazar los parmetros en el momento de la
ejecucin.EstalistasealmacenaenlacoleccinParametersdelSqlCommand.AntesdelaejecucindelSqlCommand,
es necesario crear los objetos SqlParameter y aadirlos a la coleccin. Para cada SqlParameter, hay que
proporcionar:

Elnombredelparmetro.

Elvalordelparmetro.

Ladireccindeutilizacindelparmetro.

Lasdosprimerasinformacionesseindicandurantelaconstruccindelobjeto:

Dim paramCodigoCliente As SqlParameter


paramCodigoCliente = New SqlParameter("@Codigo", codigoCliente)

La direccin de utilizacin indica si la informacin contenida en el parmetro es pasada al cdigo SQL para su
ejecucin(Input),osilecorrespondealaejecucindelcdigoSQLmodificarelvalordelparmetro(Output)olos
dos(InputOutput).LapropiedadDirectiondelaclaseSqlParameterindicaelmododeutilizacindelparmetro.

- 8-

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

El parmetro est ahora preparado para aadirse a la coleccin Parameters. Conviene comprobar en este
momento si la consulta utiliza parmetros annimos. Se deben aadir los parmetros a la coleccin
obligatoriamente en el orden de su aparicin en la consulta. Si se utilizan los parmetros nominales, no es
necesariorespetarestaregla,aunquesprudente,porsiundaelcdigoSQLesmodificadoydejadeutilizarlos
parmetros nominales. Podra ser el caso si debe cambiar de tipo proveedor de datos y el nuevo no acepta los
parmetrosnominalesenunainstruccinSQL.AhoraelSqlCommandestlistoparalaejecucin.Hayqueobservar
que,conestasolucin,notenemosquepreocuparnosdeltipodevaloresperadoporlainstruccinSQLparasaber
sidebemosenmarcarloconcaracteres.SiseutilizanparmetrosenlasalidadelainstruccinSQL,soloestarn
disponibles despus del cierre delDataReader. El siguiente ejemplo muestra, adems del nombre del cliente, el
nmerodepedidosyapasados:

Imports System.Data.SqlClient
Module TestBuscarConcat
Dim cmd As SqlCommand
Dim ctn As SqlConnection
Dim lector As SqlDataReader
Dim codCliente As String
Dim paramCodCliente As SqlParameter
Dim paramNbComandos As SqlParameter
Public Sub main()
ctn = New SqlConnection()
ctn.ConnectionString = "Data Source=localhost;
Initial Catalog=Northwind;Integrated Security=true"
ctn.Open()
cmd = New SqlCommand
cmd.Connection = ctn
Console.Write("introducir el cdigo del cliente buscado:")
codCliente = Console.ReadLine()
cmd.CommandText = " SELECT * from Customers WHERE CustomerID =
@Codigo;select @nbPed=count(orderid) from orders where customerid=@codigo"
paramCodCliente = New SqlParameter("@Codigo", codCliente)
paramCodCliente.Direction = ParameterDirection.Input
cmd.Parameters.Add(paramCodCliente)
paramNbPedidos = New SqlParameter("@nbPed", Nothing)
paramNbPedidos.Direction = ParameterDirection.Output
cmd.Parameters.Add(paramNbPedidos)
lector = cmd.ExecuteReader
Do While lector.Read
Console.WriteLine("nombre del cliente:{0}", lector("ContactName"))
Loop
lector.Close()
Console.WriteLine("este cliente ha pasado {0} pedido(s)",
cmd.Parameters ("@nbPed").Value)
ctn.Close()
Console.ReadLine()
End Sub

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

- 9-

End Module

e.Ejecucindeunprocedimientoalmacenado
Los procedimientos almacenados son elementos de una base de datos que corresponden a un conjunto de
instrucciones SQL que pueden ser ejecutadas con una simple llamada a su nombre. Son verdaderos programas
SQLquepuedenrecibirparmetrosydevolvervalores.Adems,losprocedimientosalmacenadossonregistrados
enelcachdelservidor,conlaformacompilada,durantesuprimeraejecucin,loqueaumentasusprestaciones
paralassiguientesejecuciones.Otraventajadelosprocedimientosalmacenadosescentralizarenelservidorde
basededatostodosloscdigosSQLdeunaaplicacin.Sisedebenaportarmodificacionesenlasinstrucciones
SQL, solo tendr que hacerlo en el servidor sin que sea preciso retomar el cdigo de la aplicacin, es decir, sin
tenerquevolveragenerarydesplegarlaaplicacin.
La llamada desde Visual Basic a un procedimiento almacenado es prcticamente igual a la ejecucin de una
instruccin SQL. La propiedad CommandText contiene el nombre del procedimiento almacenado. Tambin puede
modificar la propiedad CommandType con el valor CommandType.StoredProcedure para indicar que la propiedad
CommandText contiene el nombre de un procedimiento almacenado. Como para una instruccin SQL, un
procedimiento almacenado puede utilizar parmetros en entrada o en salida. Hay un tercer tipo de parmetro
disponible para los procedimientos almacenados en el tipo ReturnValue. Este tipo de parmetro sirve para
recuperar el valor devuelto por la instruccin Return del procedimiento almacenado (mismo principio que una
funcinVisualBasic).Paraprobarestasnuevasnociones,vamosautilizarelsiguienteprocedimientoalmacenado
quedevuelveelimportetotaldetodoslospedidospasadosporuncliente.

CREATE PROCEDURE TotalCliente

@code nchar(5) AS

declare @total money


select @total=sum(UnitPrice*Quantity*(1-Discount)) from Orders,
[Order Details]
where customerid=@code and Orders.orderid=[order details].orderid
return @total
GO

A nivel del cdigo Visual Basic, debemos indicar que se trata de la ejecucin de un procedimiento almacenado y
agregarunparmetropararecuperarelvalorderetornodedichoprocedimiento.Esteparmetrodebellamarse
RETURN_VALUE.

Imports System.Data.SqlClient
Module TestProcedimientoAlmacenado
Dim cmd As SqlCommand
Dim ctn As SqlConnection
Dim paramCodCliente As SqlParameter
Dim paramCantidad As SqlParameter
Dim codCliente As String
Public Sub main()
Console.Write("introducir el cdigo del cliente buscado:")
codCliente = Console.ReadLine()
ctn = New SqlConnection()
ctn.ConnectionString = "Data Source=localhost;Initial
Catalog=Northwind; Integrated Security=true"
ctn.Open()
cmd = New SqlCommand

- 10 -

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

cmd.Connection = ctn
cmd.CommandText = "TotalCliente"
cmd.CommandType = CommandType.StoredProcedure
paramCodCliente = New SqlParameter("@Cod", codCliente)
paramCodCliente.Direction = ParameterDirection.Input
cmd.Parameters.Add(paramCodCliente)
paramCantidad = New SqlParameter("RETURN_VALUE", SqlDbType.Decimal)
paramCantidad.Direction = ParameterDirection.ReturnValue
cmd.Parameters.Add(paramCantidad)
cmd.ExecuteNonQuery()
Console.WriteLine("Este cliente ha pasado {0} euros de pedido",
paramCantidad.Value)
Console.ReadLine()
ctn.Close()
End Sub
End Module

Editions ENI Tous droits rservs Copie personnelle de henry Zacarias Ingaruca

- 11 -

Vous aimerez peut-être aussi