Sql server SQL:循环遍历文件夹并发送带有附件和存档文件的电子邮件。Exec sp_Send_dbmail

Sql server SQL:循环遍历文件夹并发送带有附件和存档文件的电子邮件。Exec sp_Send_dbmail,sql-server,tsql,ssis,sp-send-dbmail,Sql Server,Tsql,Ssis,Sp Send Dbmail,大家好–我正在尝试创建以下存储过程,患者应在其中通过电子邮件接收附件文档 文档位于文件夹中,每个文档文件名(例如:LetterPatient_12345)都附加了一个患者ID(12345)。如何创建存储过程以在文件夹中查找患者ID。 下面是按患者ID显示所有文档的文件夹 W:\Files\Shared\Letters\Test 信号:12345 信号56789 病人信10112 以下是插入上述查询的完整存储过程: Declare @From nvarchar(max) = 'Dev <De

大家好–我正在尝试创建以下存储过程,患者应在其中通过电子邮件接收附件文档

文档位于文件夹中,每个文档文件名(例如:LetterPatient_12345)都附加了一个患者ID(12345)。如何创建存储过程以在文件夹中查找患者ID。 下面是按患者ID显示所有文档的文件夹

W:\Files\Shared\Letters\Test

信号:12345

信号56789

病人信10112

以下是插入上述查询的完整存储过程:

Declare @From nvarchar(max) = 'Dev <Development@un.org>'

DECLARE @Mail_Profile_Name VARCHAR(100)

SET @Mail_Profile_Name='DoNotReply'

DECLARE @MessageBody NVARCHAR(Max)

DECLARE @RecipientsList NVARCHAR(max) 

DECLARE @MailSubject NVARCHAR(500) = 'Reports'

DECLARE @EmailID INT

DECLARE @FirstName varchar(100),@LastName varchar(100)

DECLARE Email_cursor CURSOR FOR

Select distinct  PE.EmailAddress, lr.PatientFirstName, lr.PatientLastName, 
Lr.PatientId   from Letterrequest lr

Left join Patient PT on PT.PatientId = Lr.PatientId

Left join PatientEmail PE ON PE.PatientId = lr.PatientId

where 1=1

and PT.AssistanceCommunicationMethodId = 1

and PE.PreferredEmailIndicator = 1

and PE.InactiveDateTime IS NULL


OPEN Email_cursor 

FETCH NEXT FROM Email_cursor  INTO @RecipientsList,@FirstName,@LastName

WHILE @@FETCH_STATUS = 0

  BEGIN


  SET @MessageBody = 'Dear ' + @FirstName + COALESCE(' ' + @LastName,'') + CHAR(13) + CHAR(10) + 'Please find the letter attached '


  EXEC msdb.dbo.sp_send_dbmail

    @profile_name = @Mail_Profile_Name,

    @recipients = @RecipientsList,

    @body = @MessageBody,

    @subject = @MailSubject,

@Body_Format = 'HTML' ,

@from_address  = @From;




FETCH NEXT FROM Email_cursor  INTO @RecipientsList,@FirstName,@LastName

  END

CLOSE Email_cursor

DEALLOCATE Email_cursor
Declare@From nvarchar(max)='Dev'
声明@Mail\u Profile\u Name VARCHAR(100)
设置@Mail\u Profile\u Name='DoNotReply'
声明@MessageBody-NVARCHAR(最大值)
声明@RecipientsList NVARCHAR(最大值)
声明@MailSubject NVARCHAR(500)=“报告”
声明@EmailID INT
声明@FirstName varchar(100),@LastName varchar(100)
声明的电子邮件\u光标
选择不同的PE.EmailAddress、lr.PatientFirstName、lr.PatientLastName、,
Lr.PatientId来自Letterrequest Lr
左连接患者PT在PT.PatientId=Lr.PatientId上
左连接PatientEmail PE ON PE.PatientId=lr.PatientId
其中1=1
和PT.AssistanceCommunicationMethodId=1
和PE.PreferredEmailIndicator=1
并且PE.InactiveDateTime为空
用光标打开电子邮件
从电子邮件光标中提取下一个到@RecipientsList、@FirstName、@LastName
而@@FETCH\u STATUS=0
开始
SET@MessageBody='Dear'+@FirstName+COALESCE(''+@LastName',)+CHAR(13)+CHAR(10)+'请查找附件中的字母'
EXEC msdb.dbo.sp_send_dbmail
@profile\u name=@Mail\u profile\u name,
@收件人=@RecipientsList,
@body=@MessageBody,
@subject=@MailSubject,
@Body_Format='HTML',
@from_address=@from;
从电子邮件光标中提取下一个到@RecipientsList、@FirstName、@LastName
结束
用光标关闭电子邮件
取消分配电子邮件\u游标

首先,需要调整光标并添加@PatientId变量

从电子邮件中获取下一个\u光标到 @收件人名单,@FirstName,@LastName,@PatientId

以此为参考:

在使用xp_DirTree存储过程时,下面是一个示例,说明如何完成您所追求的目标:

DECLARE @FilePath NVARCHAR(500);
DECLARE @FileAttachment NVARCHAR(MAX) = ''
DECLARE @PatientID INT

SET @PatientID = 20181002

SET @FilePath = N'W:\Files\Shared\Letters\Test';

DECLARE @FileList TABLE
    (
        [FileName] NVARCHAR(500)
      , [depth] INT
      , [file] INT
    );

--using xp_DirTree:
--Parameters:
--directory - This is the directory you pass when you call the stored procedure; for example 'D:\Backup'.
--depth  - This tells the stored procedure how many subfolder levels to display.  The default of 0 will display all subfolders.
--isfile - This will either display files as well as each folder.  The default of 0 will not display any files.

--This gets a list of ALL files in your directory
--This before your cursor
INSERT INTO @FileList (
                          [FileName]
                        , [depth]
                        , [file]
                      )
EXEC [master].[sys].[xp_dirtree] @FilePath
                               , 1
                               , 1;


--Add this code inside your cursor to filter on only those files that contain the @PatientId and build out the string of files to attach.
SELECT @FileAttachment = @FileAttachment + @FilePath + '\' + [FileName] + ';'
FROM   @FileList
WHERE PATINDEX('%' + CONVERT(NVARCHAR, @PatientID) + '%', [FileName]) <> 0

--This just removes the trailing ;
SET @FileAttachment = SUBSTRING(@FileAttachment,1,LEN(@FileAttachment)-1)

--Then you can add the @file_attachments parameter to sp_send_dbmail and set that equal to the @FileAttachment variable.
SELECT @FileAttachment
声明@FilePath NVARCHAR(500);
声明@FileAttachment NVARCHAR(最大值)=”
声明@PatientID INT
设置@PatientID=20181002
设置@FilePath=N'W:\Files\Shared\Letters\Test';
声明@FileList表
(
[FileName]NVARCHAR(500)
,[depth]INT
,[file]INT
);
--使用xp_目录树:
--参数:
--目录-这是调用存储过程时传递的目录;例如“D:\Backup”。
--深度-这告诉存储过程要显示多少子文件夹级别。默认值0将显示所有子文件夹。
--isfile-这将显示文件以及每个文件夹。默认值0将不显示任何文件。
--这将获取目录中所有文件的列表
--这在光标之前
插入到@FileList中(
[文件名]
,[深度]
,[文件]
)
EXEC[master].[sys].[xp\u dirtree]@FilePath
1.
1.
--将此代码添加到光标中,以仅过滤包含@PatientId的文件,并生成要附加的文件字符串。
选择@FileAttachment=@FileAttachment+@FilePath+'\'+[FileName]+';'
来自@FileList
其中PATINDEX(“%”+CONVERT(NVARCHAR,@PatientID)+“%”,[FileName])0
--这只是去除了尾随;
设置@FileAttachment=SUBSTRING(@FileAttachment,1,LEN(@FileAttachment)-1)
--然后可以将@file\u attachments参数添加到sp\u send\u dbmail中,并将其设置为等于@FileAttachment变量。
选择@FileAttachment

只是文件所在目录上的一个旁注。运行SQL Server服务的帐户必须能够访问文件所在的目录或SQL代理,或者如果通过代理帐户运行,则必须具有访问权限。我假设“W:\”位于执行此存储过程的服务器上。如果没有,则需要从服务器和帐户访问。

是否所有文件都遵循LetterPatient_PatientId的命名约定?@TimMylott:否,文件命名约定将更改。但是文件名的末尾会有patientid,所有这些都是文件名的pdf示例:LetterPatient\u patientid MailAssistance\u 1\u patientid Premiumastation\u 123\u patientid为什么要使用存储过程?为什么不将简单脚本(python?)与SQL查询结合使用(如果您想从数据库中获取数据)。。了解何时触发也会有所帮助。