Visual Basic Foro
Programación => Visual Basic .NET / C# => Mensaje iniciado por: ADONAIRAFA en Marzo 31, 2012, 10:33:19 pm
-
Bueno, esto es la continuación de lo colocado en el Sub Foro de Bases de Datos, en el post de "Guardar imágenes en una BD"
Bueno cristian_19a, espero que veas esto:
Saludos !!!
Otra vez yo con el "temita" este de guardar las imágenes, Pero como los "perros de caza", hasta no tener "asegurada la presa", no la dejo !!!
Esto es para cristian_19a ...
Tengo una duda en cuanto al código que subiste a www.4shared.com, para la versión .NET, pero antes que los moderadores nos corran a "escobazo limpio" por publicar temas en lugares inadecuados, voy a colocarlo en el subforo de .NET
Este es una porción del mismo:
Private Sub btnGra_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGra.Click
Conectar()
Dim cmdIns As New FbCommand("INQUILINO_GRABAR", conexion)
cmdIns.CommandType = CommandType.StoredProcedure
cmdIns.Parameters.AddWithValue("@XINQ_COD", lblCod.Text)
cmdIns.Parameters.AddWithValue("@XINQ_APE", txtApe.Text)
cmdIns.Parameters.AddWithValue("@XINQ_NOM", txtNom.Text)
cmdIns.ExecuteNonQuery()
If FileName <> "" Then
Dim xByt As Byte()
xByt = ReadBinaryFile(FileName)
Dim cmdFot As New FbCommand("INQUILINO_IMG_GRABAR", conexion)
cmdFot.CommandType = CommandType.StoredProcedure
cmdFot.Parameters.AddWithValue("@xcodigo", lblCod.Text)
cmdFot.Parameters.AddWithValue("@ximg", xByt)
cmdFot.ExecuteNonQuery()
End If
Desconectar()
Limpiar()
Imagen_nulo(Me.PictureBox1, "NN")
Listar()
griDat.ClearSelection()
Habilitar(True, False)
End Sub
Se trata de estas líneas en particular:
Dim cmdIns As New FbCommand("INQUILINO_GRABAR", conexion)
cmdIns.CommandType = CommandType.StoredProcedure
Dim xByt As Byte()
xByt = ReadBinaryFile(FileName)
Dim cmdFot As New FbCommand("INQUILINO_IMG_GRABAR", conexion)
cmdFot.CommandType = CommandType.StoredProcedure
cmdFot.Parameters.AddWithValue("@xcodigo", lblCod.Text)
cmdFot.Parameters.AddWithValue("@ximg", xByt)
cmdFot.ExecuteNonQuery()
Bueno, se que tienes unos procedimientos creados "INQUILINO_GRABAR" y "INQUILINO_IMG_GRABAR", pero (y perdona la pregunta ::)) donde los creaste, donde se encuentran, porque en el archivo que subiste no.
Otra cosa la definición de xByt como un array de Bytes, pero no veo donde se le asigna algún subÍndice, y luego sin más, es pasado como parámetro en:
cmdFot.Parameters.AddWithValue("@ximg", xByt)
Y tampoco se le asigna un subíndice.
Digo esto, porque traté de cambiar el método de inserción utilizado por "INSERT INTO", pero al querer utilizar 'xByt' me perdí :'( :'( :'(
A ver, ojalá puedas tener la solución para lo del INSERT INTO, o por lo menos, saber de los procedimientos almacenados.
Saludos !!!
Manuel F. Borrego S. 8)
Barcelona, Venezuela.
-
El archivo de la base de datos esta en la carpeta bin\Debug se llama CUARTO.FDB
si utilizas IBExpert podras ver que existe dos tablas que son INQUILINO,INQUILINO_IMG y 3 procedimientos
INQUILINO_ELIMINAR, INQUILINO_GRABAR, INQUILINO_IMG_GRABAR
donde la estructura de las tablas y los procedimientos es:
CREATE TABLE INQUILINO (
INQ_COD INTEGER NOT NULL,
INQ_APE VARCHAR(30) NOT NULL,
INQ_NOM VARCHAR(30) NOT NULL
);
ALTER TABLE INQUILINO ADD CONSTRAINT PK_INQUILINO PRIMARY KEY (INQ_COD);
CREATE TABLE INQUILINO_IMG (
CODIGO INTEGER NOT NULL,
IMG BLOB SUB_TYPE 0 SEGMENT SIZE 80
);
ALTER TABLE INQUILINO_IMG ADD CONSTRAINT PK_INQUILINO_IMG PRIMARY KEY (CODIGO);
CREATE PROCEDURE INQUILINO_ELIMINAR (
xcodigo integer)
as
begin
DELETE FROM inquilino_img WHERE CODIGO = :xcodigo;
DELETE FROM inquilino WHERE INQ_COD = :xcodigo;
suspend;
end
CREATE PROCEDURE INQUILINO_GRABAR (
xinq_cod integer,
xinq_ape varchar(30),
xinq_nom varchar(30))
as
begin
UPDATE OR INSERT INTO INQUILINO (INQ_COD,INQ_APE,INQ_NOM) VALUES
(:XINQ_COD,:XINQ_APE,:XINQ_NOM);
SUSPEND;
END
CREATE PROCEDURE INQUILINO_IMG_GRABAR (
xcodigo integer,
ximg blob sub_type 0 segment size 80)
as
BEGIN
UPDATE OR INSERT INTO inquilino_img (CODIGO, IMG) VALUES
(:XCODIGO, :XIMG);
SUSPEND;
ENDbueno esta es una solución con procedimientos almacenados
ahora si quieres ejecutar un comando de linea de texto desde el aplicativo
el código del botón Grabar cambia por esto para que ya no utilices los procedimientos almacenados de INQUILINO_GRABAR y INQUILINO_IMG_GRABAR
Private Sub btnGra_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGra.Click
Conectar()
Dim cmdIns As New FbCommand("UPDATE OR INSERT INTO INQUILINO (INQ_COD,INQ_APE,INQ_NOM) VALUES('" & lblCod.Text & "','" & txtApe.Text & "','" & txtNom.Text & "');", conexion)
'cmdIns.CommandType = CommandType.Text 'Tipo de comando linea de texto no es necesario declararlo
cmdIns.ExecuteNonQuery()
If FileName <> "" Then
Dim xByt As Byte()
xByt = ReadBinaryFile(FileName)
Dim cmdFot As New FbCommand("UPDATE OR INSERT INTO inquilino_img (CODIGO, IMG) VALUES('" & lblCod.Text & "',@IMG);", conexion) 'Creamos el comando
'cmdFot.CommandType = CommandType.Text 'Tipo de comando linea de texto no es necesario declararlo
Dim xParImg As New FbParameter("@IMG", FbDbType.Binary) 'Creamos el parámetro de tipo Binario
xParImg.Value = xByt 'Le asignamos el valor al parámetro
cmdFot.Parameters.Add(xParImg) 'Añadimos el parámetro al Comando
cmdFot.ExecuteNonQuery()
End If
Desconectar()
Limpiar()
Imagen_nulo(Me.PictureBox1, "NN")
Listar()
griDat.ClearSelection()
Habilitar(True, False)
End Subbueno aquí para dar una solución he declarado un parámetro temporal por que no se puede mandar arrays en una sola cadena
Gracias
-
Excelente, voy a probarlo, y luego te comento.
No podía ver la BD, debido a que tu la tienes en versión 2.5 y yo manejo la 2.1, entonces fui revisando tu código, y fui construyendo la Base de Datos CUARTO.FDB en versión 2.1, y como pòdrás deducir, no pude ver los procedimientos almacenados.
Gracias Broth !!!
Manuel F. Borrego S. 8)
-
Ok entiendo (y)
-
Saludos cristian_19a (y a todos los que miran este post !!!) ;D ;D ;D
Esta va para tí cristian_19a: Estuve examinando tu código, los procedimientos almacenados en la BD (confieso que no sabía como buscarlos bien en el IBExpert :-[, y despues de conseguirlos, luego no sabía como crearlos :-[ :-[ :-[, pero a "carajazo limpio" >:( :P >:( fui aprendiendo hasta que se convirtió el crearlos, -relativamente en un paseo- :o) Y empecé a comprender el funcionamiento de casi todo (de paso, mis felicitaciones por el código que creaste :o :o :o). Ahora, lo tomé, y solo le hice unas pequeñas adaptaciones en función de utilizarlo en una aplicación algo más compleja (que es la que estoy diseñando en estos momentos, a manera de práctica).
Bueno dicho todo esto, tengo una inquietud... :o
Se trata de que en la mayoría de los Subs y Functions (en los que trabaja con la BD) Se aplica el abrir el objeto connection y volverlo a cerrar en la rutina local, creí que eran cosas que aplicaste al programa, por cuestiones didácticas, por decirlo así. ::) Entonces cree un módulo y en él coloqué mis clásicas subrutinas de conexión y desconexión, ya que por "costumbre" abro la conexión con la BD al iniciar la aplicación y la misma se termina al cerrar el programa, y ahí empezaron a aparecer el error en algunos casos, de que la conexión está cerrada (¿pero como? revisé el codigo a ver si era que se cerraba por "accidente", pero no !!!) y entonces lanza la excepción que no puede controlar, en otros casos, el error era que debe existir un objeto válido de conexión.
Entonces, en las rutinas donde me lanzaba la excepción, tuve agregar algo así:
If FbConn.State = ConnectionState.Open Then
FbConn.Close()
FbConn.Open()
Else
FbConn.Open()
End If
Si ya sé ::), puede parecer una redundancia, pero a partir de allí, funcionó perfecto (y resulta que es muuuy parecido a lo que colocaste en el código :-[
Podrías (o podrían) decirme a que se debe esto, a que la conexión se tome como si estuviese cerrada, cuando a mi parecer no se ha dado la "orden" para ello !!!
Saludos a todos !!!
Manuel F. Borrego S. 8)
Barcelona, Venezuela.
-
Factorizando, no seria mejor:
If FbConn.State = ConnectionState.Open Then FbConn.Close()
FbConn.Open()
-
Hey Broth !!! como está todo? ;D
Factorizando, no seria mejor:
If FbConn.State = ConnectionState.Open Then FbConn.Close()
FbConn.Open()
Tienes razón !!!, mucho mejor, eficiente y más estético de esa forma !!! :o
Ahora, las preguntas... ¿Por qué tengo usar ese fragmento de código en varios de los procedimientos de inserción, actualización y eliminación?
¿Acaso será porque estoy trabajando con procedimientos almacenados?
¿Será porque estoy trabajando con imágenes gurdadas "binariamente" en la BD?
Saludos !!!
Manuel F. Borrego S. 8)
-
jejejej ese era un ejemplo
claro de esa forma que te enviado demora un poquito el proceso de conectar
pueden abrir la conexion al momento de ejecutar tu aplicacion y antes de cerrar tu aplicacion cerrar la conexion
y los sub de conectar y desconectar lo comentas o lo borras
y asi seria mucho mas rapido
-
Bueno cristian_19a, eso justamente fue lo que hice, y me aparecieron unos cuantos problemas, fíjate en lo descubrí, lo puse así:
Saludos cristian_19a (y a todos los que miran este post !!!) ;D ;D ;D
Esta va para tí cristian_19a: Estuve examinando tu código, los procedimientos almacenados en la BD (confieso que no sabía como buscarlos bien en el IBExpert :-[, y despues de conseguirlos, luego no sabía como crearlos :-[ :-[ :-[, pero a "carajazo limpio" >:( :P >:( fui aprendiendo hasta que se convirtió el crearlos, -relativamente en un paseo- :o) Y empecé a comprender el funcionamiento de casi todo (de paso, mis felicitaciones por el código que creaste :o :o :o). Ahora, lo tomé, y solo le hice unas pequeñas adaptaciones en función de utilizarlo en una aplicación algo más compleja (que es la que estoy diseñando en estos momentos, a manera de práctica).
Bueno dicho todo esto, tengo una inquietud... :o
Se trata de que en la mayoría de los Subs y Functions (en los que trabaja con la BD) Se aplica el abrir el objeto connection y volverlo a cerrar en la rutina local, creí que eran cosas que aplicaste al programa, por cuestiones didácticas, por decirlo así. ::) Entonces cree un módulo y en él coloqué mis clásicas subrutinas de conexión y desconexión, ya que por "costumbre" abro la conexión con la BD al iniciar la aplicación y la misma se termina al cerrar el programa, y ahí empezaron a aparecer el error en algunos casos, de que la conexión está cerrada (¿pero como? revisé el codigo a ver si era que se cerraba por "accidente", pero no !!!) y entonces lanza la excepción que no puede controlar, en otros casos, el error era que debe existir un objeto válido de conexión.
Entonces, en las rutinas donde me lanzaba la excepción, tuve agregar algo así:
If FbConn.State = ConnectionState.Open Then
FbConn.Close()
FbConn.Open()
Else
FbConn.Open()
End If
Si ya sé ::), puede parecer una redundancia, pero a partir de allí, funcionó perfecto (y resulta que es muuuy parecido a lo que colocaste en el código :-[
Podrías (o podrían) decirme a que se debe esto, a que la conexión se tome como si estuviese cerrada, cuando a mi parecer no se ha dado la "orden" para ello !!!
A eso, es lo que hago referencia...
Saludos !!!
-
la conexion a la base de datos se abre solo UNA ves en todo el programa, debe hacerce en el Sub_Main de un modulo y nunca hay que abrirla ni cerrarla a cada rato.
-
seba !!! eso es lo que he tratado de hacer !!! ::) y lo expliqué en la cita, pero cuando hago tradicionalmente (abrirla al inicio de aplicación, y cerrarla al terminar) me lanza excepciones de objeto de conexión no válidos, o de objetos cerrados, he revisado el código, y se supone que deberá estar la conexión abierta, y no se por que carajo me sale esa excepción !!!
Saludos !!!
-
la variable tipo connection de lo que sea (SQLConnection, OledbConnection...) la debes declarar como Public en un modulo normal (no modulo de clase), por ejemplo Public vConecion As New SQLConnection y despues en el Sub_Main le haces el Open, obviamente debes cambiar en las propiedades del proyecto que comienze por el Sub_Main y no por el Load del formulario principal, sino la conexion no se abre nunca, pone un punto de interrupcion en el sub_main del modulo y valida que este abriendo la conexion.
saludos.
-
Seba, hice lo que me dijiste, y sigue presentando las mismas excepciones si no se verifica la conexión: preguntar si está abierta, si lo está cerrarla y abrirla nuevamente... Esta vaina me pasa desde que estoy haciendo las pruebas con datos e imágenes y procedimeintos almacenados.
Ya se me "agotaron los recursos" !!! >:( :-[
Aquí coloco el link donde subí el programa: se llama ImageInDB lo único es que su BD está basada en Firebird 2.1 (a nivel de SQL se trabaja similar a SQLServer, MySql, pero ya lo sabes mejor que yo :o)
http://www.4shared.com/zip/25qbA7CI/ImageInDB.html
(http://www.4shared.com/zip/25qbA7CI/ImageInDB.html)
De todas maneras aquí coloco la estructura de la BD:
2 Tablas:
Personal Foto_Personal
- Per_Id -------------->> Integer - Fto_Id --------------->> Integer
- Per_Ape ------------>> VarChar(50) - Fto_Img ------------>> Blob (Size 80 - Binary)
- Per_Nom ----------->> VarChar(50)
- Per_Fec ------------>> VarChar(12)
Y por último, 3 Procedimientos almacenados:
Delete_Pers_Pict:
CREATE OR ALTER PROCEDURE DELETE_PERS_PICT (
xcode integer)
as
begin
delete from personal where Per_Id = :xcode;
delete from foto_personal where Fto_Id = :xcode;
suspend;
end
Save_Picture:
CREATE OR ALTER PROCEDURE SAVE_PICTURE (
xcode integer,
ximage blob sub_type 0 segment size 80)
as
begin
insert into foto_personal (FTO_ID, FTO_IMG) values
(:xcode, :ximage);
suspend;
end
Update_Picture:
CREATE OR ALTER PROCEDURE UPDATE_PICTURE (
xcode integer,
ximage blob sub_type 0 segment size 80)
as
begin
update foto_personal set FTO_IMG = :ximage
where FTO_ID = :xcode;
suspend;
end
Saludos !!!
-
lo podes subir a otro servidor ? no tengo ganas de registrarme 8)
-
Listo Seba, lo subí por aquí:
http://netload.in/datei1218bUd6KK/ImageInDB_II.zip.htm (http://netload.in/datei1218bUd6KK/ImageInDB_II.zip.htm)
Espero sirva.
Manuel F. Borrego S. 8)
-
hola tío bueno lo que subí antes era un ejemplo en la cual fue ami manera programarlo
tu dices que tienes que cerrar y abrir la conexión
fíjate en en la función de LocateImage
si te dan cuenta se abre un comando en la conexion:
FbConn.CreateCommand
comentala y en la que sigue te tiene que quedar asi:
Dim FbDR As FbDataReader = FbCmd.ExecuteReader '(CommandBehavior.CloseConnection)
y asi no tendras problemas de cerrar y abrir
a otra cosa si te das cuenta retorna la ruta de la imagen que es un string
entonces en tu evento dgvPersonal_CellClick del grid donde eliminas la imagen del disco
If Trim(xPath) <> "" Then
Kill(xPath)
End If
estaba asi If Trim(xPath) <> 0 Then por eso no eliminaba la imagen del disco
mas no compararlo con un entero
eso es lo unico que pude ver del codigo por que me sale un error de Visual Basic PowerPacks
mas tarde lo descargo ese complemento y chekeo mas
--------------------------------
ya lo descargue y ya cheque todo el código no te hagas mucho rollo por algo simple
subí nuevamente tu código para que lo cheques como quedo
http://www.4shared.com/rar/SYi1X-Ix/ImageInDB_II.html (http://www.4shared.com/rar/SYi1X-Ix/ImageInDB_II.html)
contraseña para acceder es: 123456
Gracias
-
Gracias por responder Broth !!!
Lo que pasa, es que implementé el ejemplo en una aplicación pequeña, para luego llevarla a una más grande.
Ya lo descargo, examino y pruebo el código. Luego te comento !!!
Saludos !!!
Manuel F. Borrego S. 8)
-
Ok tio cualquier cosa no dudes en comentar.
Gracias