2012-09-14 173 views
5

Tengo una pregunta de dos partes relacionada con el envío de resultados de consulta como archivos adjuntos utilizando sp_send_dbmail.sp_send_dbmail adjuntar archivos almacenados como varbinary en la base de datos

Problema 1: Solo se abrirán los archivos .txt básicos. Cualquier otro formato como .pdf o .jpg está dañado.

Problema 2: Al intentar enviar varios archivos adjuntos, recibo un archivo con todos los nombres de los archivos pegados.

estoy ejecutando SQL Server 2005 y tengo una tabla que almacena los documentos cargados:

CREATE TABLE [dbo].[EmailAttachment](
[EmailAttachmentID] [int] IDENTITY(1,1) NOT NULL, 
[MassEmailID] [int] NULL, -- foreign key 
[FileData] [varbinary](max) NOT NULL, 
[FileName] [varchar](100) NOT NULL, 
[MimeType] [varchar](100) NOT NULL 

También tengo una mesa con cosas MassEmail de correo electrónico estándar. Aquí está el script SQL Send Mail. Por brevedad, he excluido declaraciones de declaración.

while ((select count(MassEmailID) from MassEmail where status = 20)>0) 
begin 
    select @MassEmailID = Min(MassEmailID) from MassEmail where status = 20 
    select @Subject = [Subject] from MassEmail where MassEmailID = @MassEmailID 
    select @Body = Body from MassEmail where MassEmailID = @MassEmailID 

    set @query = 'set nocount on; select cast(FileData as varchar(max)) from Mydatabase.dbo.EmailAttachment where MassEmailID = '+ CAST(@MassEmailID as varchar(100)) 

    select @filename = '' 
    select @filename = COALESCE(@filename+ ',', '') +FileName from EmailAttachment where MassEmailID = @MassEmailID 

exec msdb.dbo.sp_send_dbmail  
    @profile_name = 'MASS_EMAIL', 
    @recipients = '[email protected]', 
    @subject = @Subject, 
    @body [email protected], 
    @body_format ='HTML', 
    @query = @query, 
    @query_attachment_filename = @filename, 
    @attach_query_result_as_file = 1, 
    @query_result_separator = '; ', 
    @query_no_truncate = 1, 
    @query_result_header = 0; 

update MassEmailset status= 30,SendDate = GetDate() where MassEmailID = @MassEmailID 
end 

Soy capaz de leer correctamente los archivos de la base de datos, así sé que los datos binarios no están dañados.

Los archivos .txt solo se leen cuando lanzo FilaData a varchar. Pero claramente los encabezados originales se pierden. También vale la pena señalar que los tamaños de archivos adjuntos son diferentes a los archivos originales. Eso es muy probablemente debido a una codificación incorrecta. Así que espero que haya una forma de crear encabezados de archivos usando el tipo mimet almacenado, o alguna forma de incluir encabezados de archivos en los datos binarios.

Tampoco estoy seguro de los valores de los últimos parámetros, y sé que la fusión no es del todo correcta, ya que antepone el primer nombre de archivo con una coma. Pero una buena documentación es casi imposible de encontrar. ¡Por favor ayuda!

Respuesta

6

No creo que vayan a poder enviar datos binarios directamente desde SQL. Hay un few posts out there que habla sobre este mismo problema. Desde el Microsoft documentation, un texto devuelto a la consulta se formatea como un archivo de texto. El binario está formateado como hexadecimal. Lo cual, como ha señalado, corrompe cualquier archivo que no sea un documento de texto.

Creo que aún puede lograr lo que está tratando de hacer primero using BCP para exportar los datos binarios al sistema de archivos, y luego importarlos de nuevo a través de los métodos tradicionales de archivos adjuntos disponibles para sendmail.

Algo así. (sólo el concepto - código no probado)

DECLARE @OutputFileAndPath VarChar(500) = '\\Log_Files\MyFile.pdf ' 
DECLARE @sql VarChar(8000) 

SELECT @sql = 'BCP "SELECT MyFile FROM [dbo].[MyTable] 
    WHERE PrimaryKey = 12345" queryout ' + @OutputFileAndPath + 
     ' -S MyServer\MyInstance -T -fC:\Documents.fmt' 

/* you could use a generic format file that would cover most formats */ 

EXEC xp_cmdshell @sql, NO_OUTPUT; 

while ((select count(MassEmailID) from MassEmail where status = 20)>0) 
begin 
    select @MassEmailID = Min(MassEmailID) from MassEmail where status = 20 
    select @Subject = [Subject] from MassEmail where MassEmailID = @MassEmailID 
    select @Body = Body from MassEmail where MassEmailID = @MassEmailID 


    exec msdb.dbo.sp_send_dbmail  
     @profile_name = 'MASS_EMAIL', 
     @recipients = '[email protected]', 
     @subject = @Subject, 
     @body [email protected], 
     @body_format ='HTML', 
     @file_attachments = @OutputFileAndPath /* i.e. \\Log_Files\MyFile.pdf */ 

    update MassEmailset status= 30,SendDate = GetDate() where MassEmailID = @MassEmailID 
end  
+0

Gracias por su respuesta. Parece que podría funcionar, pero las restricciones de seguridad prohíben ejecutar xp_cmdshell, especialmente con los archivos cargados por el usuario. Parece que tendré que tomar un enfoque diferente. –

+0

cualquier suerte sobre este tema. –

Cuestiones relacionadas