Ir al contenido principal

GUARDAR DOCUMENTOS PDF EN LA BASE DE DATOS SQLSERVER DESDE .NET

Personalmente quiero contarles que para mi este proceso ha sido muy escabroso,he dedicado muchas horas de investigacion para encontrar la forma de hacerlos lo más sencillo posible.
Anteriormente había guardado imagenes en la base de datos utilizando compos de tipo imagen, pero luego revisando la documentacion de sqlserver 2005 encontre que en el
futuro este tipo de campo podría ser descartado, esto me llevo a buscar otras alternativas especialmente con los campos binarios o (varbinary(max)) .
PASOS:

1.- Primero declare las siguientes variables de clase en su formulario windows form

Dim fdlg As New OpenFileDialog

Dim fs As System.IO.FileStream

Dim mcorr_documento As Int32

Dim bw As System.IO.BinaryWriter

----- fin de las variables de clase

2.- Seguidamente en su formulario pegue un objeto de tipo OpenFileDialog que le servira para buscar el archivo que desea almacenar en la base de datos
3.- Cree un objeto de tipo Combo y agregue una lista de los tipos de archivos que desea almacenar en la base de datos, algo como esto
pdf
WORD 2000-2003
WORD 2007
docx

Esto le servira como referencia para que lo pueda almacenar en un campo de la base de datos y cuando lo recupere despues sepa que tipo de archivo esta almacenado ahi (Se puede almacenar cualquier tipo de archivo)

4.- Despues cree un botón que y dentro del clic del botón puede escribir el siguiente codigo

If Me.ComboBoxtipo_docu.Text = "" Then

MsgBox(" Debe seleccionar el formato de documento")

eturn
End If
If TextBoxbreve_desc_dcto.Text = "" Then
MsgBox("Debe escribir una breve descripción del documento almacenar")
Return
End If
If Me.Textnombre_archivo.Text = "" Then
MsgBox("Debe seleccionar un archivo a guardar")
Return
End If
'''Aqui comienza el proceso real de guardar el archivo

Dim Myfile As System.IO.FileStream
Myfile = System.IO.File.OpenRead(Me.Textnombre_archivo.Text)
Dim Arr(Myfile.Length) As Byte 'Declaramos el array para manejar los bytes almacenar
Try
Myfile.Read(Arr, 0, Myfile.Length)
Dim mysql1 As New SqlClient.SqlCommand("insert into RECLAMOS_EVIDENCIAS(CORR_REC,DESCRIPCION,DOCUMENTO,TIPO_DOCU) VALUES (@CORR_REC,@DESCRIPCION,@DOCUMENTO,@TIPO_DOCU)")
mysql1.Parameters.Add("@CORR_REC", SqlDbType.Int, 0).Value = txt_cor.Text
mysql1.Parameters.Add("@DESCRIPCION", SqlDbType.NVarChar, 100).Value = TextBoxbreve_desc_dcto.Text
mysql1.Parameters.Add("@DOCUMENTO", SqlDbType.VarBinary).Value = Arr
mysql1.Parameters.Add("@TIPO_DOCU", SqlDbType.NVarChar, 20).Value = Me.ComboBoxtipo_docu.Text
mysql1.Connection = conn ''' Con es my objeto conexion a la base de datos
mysql1.ExecuteNonQuery()
MsgBox("Documento guardado")

Catch ex As Exception

MsgBox("Error al almacenar el dato:" & ex.ToString)

End Try


5.-Ahora leamos nuestro documento de la base de datos
Dentro de un boton en el evento clic ponemos el siguiente codigo, asumiendo
que mi tabla se llama RECLAMOS_EVIDENCIAS

Dim mysql1 As New SqlClient.SqlCommand

mysql1.CommandText = "select CORRELATIVO,CORR_REC,DESCRIPCION,DOCUMENTO,TIPO_DOCU from RECLAMOS_EVIDENCIAS where correlativo =" & Me.mcorr_documento & " AND CORR_REC=" & txt_cor.Text
mysql1.Connection = conn
Dim myread As SqlClient.SqlDataReader
Try
Dim bits() As Byte

myread = mysql1.ExecuteReader
myread.Read()

'''3 indica el numero de columa del blog en el data reader
''' Aqui declaramos nuetros array de datos al tamaño que tiene en la base de datos
Dim filedata(myread.GetBytes(3, 0, Nothing, 0, Integer.MaxValue) - 1) As Byte
myread.GetBytes(3, 0, filedata, 0, filedata.Length)
Dim myext As String
Select Case myread(4)

Case "PDF"
myext = "pdf"
Case "WORD 2000-2003"
myext = "doc"
Case "WORD 2007-"
myext = "docx"
Case "JPG"
myext = "jpg"
Case "AVI"
myext = "avi"
Case Else
myext = "PDF"
End Select
'' Aqui creo el nombre del archivo a recuperar con su extension correcta
Dim ExtensionNombre As String = Application.StartupPath() & "\mydocumento." & myext
'' Aqui creamos el archivo
Dim fs As System.IO.FileStream = New System.IO.FileStream(ExtensionNombre, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write)
bw = New System.IO.BinaryWriter(fs)
bw.Write(filedata)
bw.Flush()
bw.Close()
fs.Close()
myread.Close()


''' Iniciamos la carga del documento para visuarlizarlo
Dim Command As New Process

'Creamos la instancia Process

Command.StartInfo.FileName = ExtensionNombre
Command.StartInfo.UseShellExecute = True '''importantisimo esta propiedad permite buscar en el path del windows el programa asociado para ejecutar el archivo segun su tipo
'Para redirigir la salida de este proceso esta propiedad debe ser false
Command.StartInfo.CreateNoWindow = True
Command.Start()
Catch ex As Exception

MsgBox(ex.ToString)

End Try

Espero con esto muchos puedan guadar los tipos de documentos que deseen en la base de datos y enriquecer el uso de este motor.

Comentarios

  1. Hola luis, quisiera saber como hacer para poder cargar el documento pdf o docx, pues ahi veo que defrente lo estas guardando, a ver si me respondes, ahi te dejo mi correo
    ronal_soft@hotmil.com

    ResponderEliminar
  2. ''' Iniciamos la carga del documento para visuarlizarlo
    Dim Command As New Process

    'Creamos la instancia Process

    Command.StartInfo.FileName = ExtensionNombre
    Command.StartInfo.UseShellExecute = True '''importantisimo esta propiedad permite buscar en el path del windows el programa asociado para ejecutar el archivo segun su tipo
    'Para redirigir la salida de este proceso
    Ahi mismo esta como cargarlo, es esta parte, no importa la extension del documento, windows sabe asociar los doc a su extension y buscar el software necesario para leerlo.

    esta propiedad debe ser false
    Command.StartInfo.CreateNoWindow = True
    Command.Start()
    Catch ex As Exception

    MsgBox(ex.ToString)

    ResponderEliminar
  3. Debes buscar en el ejemplo donde dice ''' Iniciamos la carga del documento para visuarlizarlo, ese codigo a continuación es el que tiene como cargar los documentos.
    si importar sea word o pdf.
    Saludos

    ResponderEliminar
  4. Gracias por compartir su conocimiento, es muy interesante la forma de grabar y mostrar documentos de esta forma tan sencilla, pero tengo una duda...

    Que significan o que tipo de información graba en estos campos de la Base de datos, nuevamente gracias por su ayuda...

    ResponderEliminar
  5. La información que se guarda ahi son documentos que una persona ha creado en Word o convertidos a PDF, el contenido de estos documentos dependera del sistema que maneje, por ejemplo si es de inventarios podrian ser especificaciones técnicas del producto, planos, etc.

    ResponderEliminar
  6. Un pequeño aporte, espero les pueda servir tanto como este articulo.

    http://micro4dev.blogspot.com/2010/03/guardar-archivos-en-base-de-datos.html

    ResponderEliminar
  7. hola luis, podrias pasarme el codigo a mi correo? gracias
    ricardo_apd@hotmail.com

    ResponderEliminar
  8. I have a question. What it's "txt_cor"
    It's not declared.
    Thanks for great Job

    ResponderEliminar
  9. Hola Luis gran aporte, estoy probandolo para ver como me resulta y si alfin puedo resolver muchos problemas sobre todo con los documentos que se pierden en la red o que nadie encuentra porque no saben donde los han guardado.

    Nuevamente Mil gracias por su tiempo en este trabajo.

    Hay una variable que no esta declarada y quisiera saber a que hace referencia esta variable "txt_cor"

    Si me pudieras colaborar, nuevamente gracias

    Cordialmente, Fernando T

    ResponderEliminar
    Respuestas
    1. Este campo solo es un correlativo usado para buscar el documento en la tabla RECLAMOS_EVIDENCIAS , si ves el ejemplo los documentos los guardo en esta tabla entonces tienen un correlativo por que a veces so muchos documentos.

      Eliminar
  10. hola
    Que buen aporte puedes enviarme el codigo a mi correo

    wfob@hotmail.com

    ResponderEliminar
  11. hola señor luis alonso buenos noches soy de venezuela me llamo wayne contreras y necesito su ayuda urgente mi correo es wayne153@hotmail.com

    ResponderEliminar
  12. Wayne, el codigo esta en la parte superior, puede copiarlo de aqui mismo.
    Saludos

    ResponderEliminar
  13. Genial tu codigo, me funciono perfecto.

    Saludos.

    ResponderEliminar
  14. Hola que tal me gustaria algo de informacion para depurar una duda la cual tengo un formulario realizado en infopath 2010 la cual guanda documentos en formato PDF pero me esta cansuando poblemas de almacemanientos en tonces lko que pretendo realizar es almacenarlos en una Base de Datos sql server 2008. espero contar con su apoyo.

    atte: Jesús

    ResponderEliminar
  15. Tu código me funciona perfectamente en una bdd que estaba preparada para ello, en
    SQL-Server 2005.
    Ahora me encuentro con el problema que estoy montando una nueva BDD en otro servidor, y el mismo código me da error:
    NO SE PUEDEN RELLENAR TABLAS, INDICES Y COLUMNAS, DE TIPO TEXT, NTEXT E IMAGE EN ESTE GRUPO DE ARCHIVOS HASTA QUE SE AGREGUE UN ARCHIVO.

    Ya digo que el código funciona bien en otro servidor. Me parece que debo habilitar algo de soporte de Filestream en la bdd pero lo he hecho y sigo con el mismo problema, ¿Alguna ayuda?

    ResponderEliminar
    Respuestas
    1. Resolviste tu problema si puedo ayudar estoy pendiente si puedes enviar imagenes o algo mas visual para poder ayudar saludos

      Eliminar
  16. Hola luis estoy haciendo el codigo tal cual como esta y al momento de ejecutar el primer boton me sale el siguiente error:No se pudo encontrar el archivo 'C:\Users\LEONARDO\AppData\Local\Temporary Projects\Archivo_Replan\bin\Debug\prueba1'. teniendo en cuenta que el archivo esta en la ruta especificada y todos los campos llenos. gracias..

    ResponderEliminar
  17. como hago para que no me acepte archivos pdf duplicados?

    ResponderEliminar
    Respuestas
    1. Podrías crear un campo en la base de datos que tenga el nombre del documento y lo validas antes, si existe mandas una alerta al usuario
      -

      Eliminar
  18. Excelente este codigo creo que a muchos nos a resulto la vida si puedo ayudar en algo estoy para ayudar y muchas gracias Luis Alonso Mendoza Flamenco si puedo ayudar en algo estoy al pendiente saludos

    ResponderEliminar
  19. hola quisiera saber como poder hacer para devolver una imagen que ya esta guardada en sql2005 en binario y recuprerarla para mostrarla en un control en picturebox para ser mas especifica

    ResponderEliminar
    Respuestas
    1. Private Function obtenerImagen(ByVal consulta As String) As System.IO.MemoryStream
      Dim myCommand As New SqlClient.SqlCommand
      Dim rdrbusqueda As SqlClient.SqlDataReader
      myCommand.CommandText = consulta
      myCommand.Connection = conn
      rdrbusqueda = myCommand.ExecuteReader
      Dim mencontro As Boolean = False
      Dim mysumadeta As String

      Dim retval As Long = 0
      Dim buffersize As Integer = 300000
      Dim outbyte(300000 - 1) As Byte
      'pbProducto.Image = Nothing
      'pbProducto.Refresh()
      Dim nombre As String = "C:\\tmp\\activos" & System.DateTime.Now.Millisecond
      Dim ms1 As New System.IO.MemoryStream
      Do While rdrbusqueda.Read()
      If Not rdrbusqueda.IsDBNull(0) Then
      retval = rdrbusqueda.GetBytes(0, 0, outbyte, 0, buffersize)
      ms1 = New System.IO.MemoryStream(outbyte)
      mencontro = True
      End If
      Loop

      'If mencontro Then
      ' pbProducto.Image = Image.FromStream(ms1)
      ' pbProducto.SizeMode = PictureBoxSizeMode.StretchImage ' Para ajustar la imagen al tamaño del objeto
      ' pbProducto.Invalidate()

      'End If
      rdrbusqueda.Close()
      'ms1.Flush()
      'ms1.Close()
      Return (ms1)

      '' Como leer una imagen de la base de datos
      ' byte[] imageBuffer = (byte[]) ds.Tables["products"].Rows[0]["productImage"];
      '// Se crea un MemoryStream a partir de ese buffer
      'System.IO.MemoryStream ms = new System.IO.MemoryStream(imageBuffer);
      '// Se utiliza el MemoryStream para extraer la imagen
      'pictureBox.Image = Image.FromStream(ms);

      End Function

      ' para llamar la funcion haces esto
      'parte para obtener la foto producto
      pbProducto.Image = Nothing
      pbProducto.Refresh()
      Dim fp As New System.IO.MemoryStream
      fp = obtenerImagen("select fproducto from molde where cod_molde='" & Me.Textcod_molde.Text & "' AND CORR_MOLDE ='" & Me.Textcorr_molde.Text & "'")
      If fp.Length <> 0 Then
      pbProducto.Image = Image.FromStream(fp)
      pbProducto.SizeMode = PictureBoxSizeMode.StretchImage ' Para ajustar la imagen al tamaño del objeto
      pbProducto.Invalidate()
      fp.Flush()
      fp.Close()
      End If
      pbmolde.Image = Nothing

      Eliminar
  20. Al tomar el codigo y colocarlo en vb 2012 arroja error en
    mysql1.Connection = conn
    conn debe ser declarado cómo eliminó el error? muchas gracias, humberto L Colombia rh_lizcano@hotmail.com

    ResponderEliminar
  21. Una conexión a la base de datos sql server se crea asi, entonces conn es el objeto de tipo

    conexión que debes tener declarado ya en tu sistema, puede tener otro nombre.

    Saludos




    ' Visual Basic
    Public Sub ConnectToSql()
    Dim conn As New SqlClient.SqlConnection
    ' TODO: Modify the connection string and include any
    ' additional required properties for your database.
    conn.ConnectionString = & _
    "integrated security=SSPI;data source=SQL Server Name;" & _
    "persist security info=False;initial catalog=northwind"
    Try
    conn.Open()
    ' Insert code to process data.
    Catch ex As Exception
    MessageBox.Show("Failed to connect to data source")
    Finally
    conn.Close()
    End Try
    End Sub

    ResponderEliminar
  22. disculpa me marca error en No se pudo encontrar el archivo 'C:\Users\Luis\Documents\Visual Studio 2015\Projects\Sicaecbtis229\Sicaecbtis229\bin\Debug\prueba'. ¿el nombre del archivo que toma desde un textbox debe estar creado?

    ResponderEliminar
  23. Hola, he realizado todo paso a paso y da muchos errores y no es a la base de datos sino con el botón guardar..... me da error antes de guardar

    ResponderEliminar
  24. HOLA YO DENUEVO. NO ME GRABA NADA ESTE ES MI BOTÓN GUARDAR:

    If Me.btn_gu.Text = "" Then
    MsgBox(" Debe seleccionar el formato de documento")
    Return
    End If

    If TextBoxbreve_desc_dcto.Text = "" Then
    MsgBox("Debe escribir una breve descripción del documento almacenar")
    Return
    End If
    If Me.Textnombre_archivo.Text = "" Then
    MsgBox("Debe seleccionar un archivo a guardar")
    Return
    End If


    Dim Myfile As System.IO.FileStream
    Myfile = System.IO.File.OpenRead(Me.Textnombre_archivo.Text)
    Dim Arr(Myfile.Length) As Byte 'Declaramos el array para manejar los bytes almacenar


    Try
    Myfile.Read(Arr, 0, Myfile.Length)


    SC.Parameters.Clear()
    SC.Connection = conexion
    SC.CommandType = CommandType.StoredProcedure
    SC.CommandText = "sp_documento"


    SC.Parameters.Add("@DESCRIPCION", SqlDbType.NVarChar, 100).Value = TextBoxbreve_desc_dcto.Text
    SC.Parameters.Add("@DOCUMENTO", SqlDbType.VarBinary).Value = Arr
    SC.Parameters.Add("@TIPO_DOCU", SqlDbType.NVarChar, 20).Value = Me.ComboBoxtipo_docu.Text

    SC.Parameters.Add("@valOpcion", SqlDbType.Char).Value = "U"

    conexion.Open()
    SC.ExecuteNonQuery()
    MsgBox("Documento guardado")

    conexion.Close()

    Catch ex As Exception

    MsgBox("Error al almacenar el dato:" & ex.ToString)

    End Try


    ResponderEliminar
  25. Un poco desordenado la explicacion para seguir como guia hay muchas cosas en las que tenemos que adivinar que es

    ResponderEliminar
    Respuestas
    1. Si le entiendo, desde el punto de vista técnico, muchas veces descuidamos el aspecto pedagógico , trataremos en próximos ejemplos hacerlos con mas detalle.

      Eliminar
  26. Buenos Días como se puede visualizar los documentos mediante el datagridview con el evento click

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Como guardar un PDF en un campo de una tabla en SQL SERVER utilizando PowerBuilder

1.- Crea un campo de tipo image en la tabla donde deseas guardar tu archivo. 2.- Luego lees el archivo pdf del path donde se encuentre 3.- Seguidamente actualizas el contenido leido en el campo de la tabla Supongamos que tenemos una tabla que se llama prueba y utiliza una llave unica sobre el campo tmp_llave. El campo campo image se llama tmp_archivo. // Declaramos nuetros campos de tipo blog blob lbl_data blob lbl_temp long ll_file, ll_long = 0, ll_tam integer li_pos = 1 // leemos el archivo ll_file = FileOpen("c:\temp\prueba.pdf",streammode!) // barremos sus registros Do While FileRead(ll_file,lbl_temp) > 0 lbl_data += lbl_temp Loop // cerramos el archivo FileClose(ll_file) // actualizamos nuestra base de datos UPDATEBLOB prueba SET prueba.tmp_archivo = :lbl_data WHERE prueba.tmp_llave = :li_llave; // Para recuperar y mostrar el archivo: SELECTBLOB tmp_archivo INTO :lbl_data FROM prueba WHERE prueba.tmp_llave = :li_llave; ll_file FileOpen("c:\temp\prueba2.pdf"

Como reparar una DB SQL

En muchas ocasiones nuestra base de datos en sqlserver 2000 se puede dañar por fallas debido a que nuestro servidor se reinicia de manera inesperada o la memoria RAM o el disco duro tienen algunos problemas. Esto origina que en la base de datos se corrompan algunos objetos como tablas o índices. Cuando tratamos de seleccionar registros en nuestra tabla nos da un error grave del ( DBPROCESS is dead, Error Severities) Aquí es donde inicia nuestro problema, no podemos acceder a los registros de la tabla; la razón puede ser según el nivel de severidad del error, estos niveles están categorizados así: EXINFO 1 Informational, nonerror. EXUSER 2 User error. EXNONFATAL 3 Nonfatal error. EXCONVERSION 4 Error in DB-Library data conversion. 5 The server has returned an error flag. EXTIME 6 Time-out period exceeded while waiting for a response from the server; the DBPROCESS is still alive. EXPROGRAM 7 Coding error in user program. EXRESOURCE 8 Running out of resources; the DBPROCESS ma