2011-05-06 9 views
7

tengo esta base de datos con una tabla que tiene la siguiente, pero no tengo manera de descifrarlos queAlmacenamiento de Microsoft Word 97 documentos en la columna de SQL Server

DATA,  TYPE,   FILE TYPE, SIZE, DOC TYPE 
0x15234324 , Word.Document.8 ,DOC,  19968, WORD.DOCUMENT.8 

El campo parece contener un documento de Word almacenada en una SQL Server IMAGE columna

¿Alguien ha encontrado esto antes o una forma de extraer estos datos en un formato legible?

Hasta ahora he intentado utilizar PHP para extraer el archivo y escribirlo en un documento de Word pero no tuve mucha suerte.

ACTUALIZACIÓN: ahora tengo Visual Studio Express y me gustaría una manera de extraer estos datos y guardar en un documento de Word

Update2: Esto es lo que tengo en VB sofar

Imports System.Data.SqlClient 
Imports System.IO 


Public Class Form1 

    Private Shared Function RetrieveFile(ByVal filename As String) As Byte() 
     Dim connection As New SqlConnection("Server=sqlsrv;database=database;Trusted_Connection=Yes;") 
     Dim command As New SqlCommand("select data from objects where object_ref in (select data from parts where object_ref =239804)", connection) 
     command.Parameters.AddWithValue("test", filename) 
     connection.Open() 
     Dim reader As SqlDataReader = command.ExecuteReader(System.Data.CommandBehavior.SequentialAccess) 
     reader.Read() 
     Dim memory As New MemoryStream() 
     Dim startIndex As Long = 0 
     Const ChunkSize As Integer = 256 
     While True 
      Dim buffer As Byte() = New Byte(ChunkSize - 1) {} 
      Dim retrievedBytes As Long = reader.GetBytes(1, startIndex, buffer, 0, ChunkSize) 
      memory.Write(buffer, 0, CInt(retrievedBytes)) 
      startIndex += retrievedBytes 
      If retrievedBytes <> ChunkSize Then 
       Exit While 
      End If 
     End While 
     connection.Close() 
     Dim data As Byte() = memory.ToArray() 
     memory.Dispose() 
     Return data 


    End Function 


    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click 
     Dim saveFileDialog1 As New SaveFileDialog() 
     saveFileDialog1.Filter = "Doc File|*.doc" 
     saveFileDialog1.Title = "Save an doc File" 
     saveFileDialog1.ShowDialog() 

     If saveFileDialog1.FileName <> "" Then 
      Dim fs As New System.IO.FileStream(saveFileDialog1.FileName, System.IO.FileMode.Create, System.IO.FileAccess.Write) 
      Dim data As Byte() = RetrieveFile("test.doc") 
      fs.Write(data, 0, data.Length) 
      fs.Flush() 
      fs.Close() 
     End If 
    End Sub 




End Class 
+0

Probablemente se podría simplemente almacenar los bytes contenidos en 'DATA' en el sistema de archivos y luego abre ese archivo con MS Word. –

+0

Cool - ¿cómo extraería esta información del servidor SQL? como la cadena parece ser corta en la ventana de resultados de la consulta de administración SQL – Rob

+3

Sí, SSMS siempre truncará a un máximo. longitud: necesitará usar algún código para capturarlo desde SQL Server. Ver esta [otra pregunta SO] (http://stackoverflow.com/questions/2818557/are-there-any-utilities-to-extract-binary-data-from-sql-server) sobre un tema similar - tal vez eso ' Te ayudaré –

Respuesta

4

me escribió un script VBS para extraer datos de SharePoint blobs hace un tiempo, he aquí una versión genérica de la misma:

Const adOpenKeyset     = 1 
Const adLockOptimistic    = 3 
Const adTypeBinary     = 1 
Const adSaveCreateOverWrite   = 2 

strSQLServer = "YOURSERVER" 
strSQLDatabase = "YOURDB" 
strRecordID = "123" 
strTempFileName = "c:\output.doc" 

Set objConn = CreateObject("ADODB.Connection") 
Set objRS = CreateObject("ADODB.RecordSet") 
Set objStream = CreateObject("ADODB.Stream") 

objConn.Open "Provider=SQLOLEDB;data Source=" & strSQLServer & ";Initial Catalog=" & strSQLDatabase & "; Trusted_Connection=yes;" 
objRS.Open "Select * from AllDocStreams WHERE ID='" & strRecordID & "'", objConn, adOpenKeyset, adLockOptimistic 

objStream.Type = adTypeBinary 
objStream.Open 
objStream.Write objRS.Fields("Content").Value 
objStream.SaveToFile strTempFileName, adSaveCreateOverWrite 

objRS.Close 
objConn.Close 
+0

He intentado lo anterior y estoy obteniendo un error de conversión en la palabra y luego el siguiente texto - ÿÿÿÿDocument Word.Document.8 Word.Document.8 æ ÐÏ à¡ ± á> þÿ Parece que la salida es incorrecta – Rob

+0

He probado esto con una palabra Documento 2007 almacenado en una base de datos Sharepoint 2007 esta mañana y parecía funcionar bien. – Dave

2

código C#:

connection.Open(); 
SqlCommand command1 = new SqlCommand("select DATA from TABLE where ...", connection); 
byte[] img = (byte[])command1.ExecuteScalar(); 
File.WriteAllBytes("your_path/word.doc", img); 

Esa debe ser la lógica. Escribe algo similar en cualquier idioma que conozcas. No debería ser difícil en PHP o lo que sea que estés usando.

+0

Mira la actualización 2 de arriba ¡Este es el código que he copiado y estoy sacando un índice de los límites! ¿algunas ideas? – Rob

0

intentar algo como esto, en lugar de los "unos" valores con su propia:

declare @doc varbinary(max), @ObjectToken int 

select @doc = (select data from yourTable were someID = @idThatYouWant) 

set @FileName = '\someFolder\' + 'someFilename.doc' 

print 'Processing: ' + isnull(@FileName, 'null') 

exec sp_oacreate 'ADODB.Stream', @objecttoken output 
exec sp_oasetproperty @objecttoken, 'type', 1 
exec sp_oamethod @objecttoken, 'open' 
exec sp_oamethod @objecttoken, 'write', null, @doc 
exec sp_oamethod @objecttoken, 'savetofile', null, @FileName, 2 
exec sp_oamethod @objecttoken, 'close' 
exec sp_oadestroy @objecttoken 
+0

esto funciona y el archivo se escribe pero abre dos veces en la palabra obteniendo un error de convertidor en la palabra y luego el siguiente texto - ÿÿÿÿDocument Word.Document.8 Word.Document.8 æ à à ± á> þÿ - Parece que el resultado es incorrecto – Rob

0

Creo obtendrá una IndexOutOfRangeException en la siguiente línea de código:

Dim retrievedBytes As Long = reader.GetBytes(1, startIndex, buffer, 0, ChunkSize) 

porque el índice del primer parámetro es 0 no 1

de todos modos Le sugiero que utilice un método como el sugerido por Klark, que es más simple y más legible.

Cuestiones relacionadas