У меня есть таблица в одной из моих баз данных, которая является очередью писем. Письма по определенным адресам накапливаются в одном письме, что делается sproc. В sproc у меня есть переменная таблицы, которую я использую для построения накопленных тел писем, а затем перебираю для отправки каждого письма. В моей таблице var мой столбец тела определен как VARCHAR(MAX)
, так как в настоящее время может быть любое количество электронных писем, накопленных для данного адреса электронной почты. Кажется, что хотя мой столбец определен как VARCHAR(MAX)
, он ведет себя так, как если бы он был VARCHAR(4000)
, и обрезает входящие в него данные, хотя он НЕ выдает любые исключения, он просто молча перестает объединять больше данных после 4000 символов.
Оператор MERGE - это место, где он встраивает накопленное тело письма в @ EMAILS.BODY, то есть поле, которое усекает себя до 4000 символов.
EDIT
Я обновил свой оператор MERGE, пытаясь привести всю назначенную строку к VARCHAR (MAX), но он все еще молча усекает себя до 4000 символов ... вот мой новый MERGE:
MERGE @EMAILS AS DST
USING (SELECT * FROM @ROWS WHERE ROWID = @CURRID) AS SRC
ON SRC.ADDRESS = DST.ADDRESS
WHEN MATCHED THEN
UPDATE SET
DST.ALLIDS = DST.ALLIDS + ', ' + CONVERT(VARCHAR,ROWID),
DST.BODY = DST.BODY +
CONVERT(VARCHAR(MAX),
'<i>'+CONVERT(VARCHAR,SRC.DATED,101)+
' '+CONVERT(VARCHAR,SRC.DATED,8)+
':</i> <b>'+SRC.SUBJECT+'</b>'+CHAR(13)+
SRC.BODY+' (Message ID '+
CONVERT(VARCHAR,SRC.ROWID)+')'+
CHAR(13)+CHAR(13)
)
WHEN NOT MATCHED BY TARGET THEN
INSERT (ADDRESS, ALLIDS, BODY) VALUES (
SRC.ADDRESS,
CONVERT(VARCHAR,ROWID),
CONVERT(VARCHAR(MAX),
'<i>'+CONVERT(VARCHAR,SRC.DATED,101)+
' '+CONVERT(VARCHAR,SRC.DATED,8)+
':</i> <b>'+SRC.SUBJECT+'</b>'+CHAR(13)+
SRC.BODY+' (Message ID '+CONVERT(VARCHAR,SRC.ROWID)+')'
+CHAR(13)+CHAR(13)
)
);
КОНЕЦ РЕДАКТИРОВАНИЯ
Ниже приведен код моего спрока ...
ALTER PROCEDURE [system].[SendAccumulatedEmails]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SENTS BIGINT = 0;
DECLARE @ROWS TABLE (
ROWID ROWID,
DATED DATETIME,
ADDRESS NAME,
SUBJECT VARCHAR(1000),
BODY VARCHAR(MAX)
)
INSERT INTO @ROWS SELECT ROWID, DATED, ADDRESS, SUBJECT, BODY
FROM system.EMAILQUEUE
WHERE ACCUMULATE = 1 AND SENT IS NULL
ORDER BY ADDRESS, DATED
DECLARE @EMAILS TABLE (
ADDRESS NAME,
ALLIDS VARCHAR(1000),
BODY VARCHAR(MAX)
)
DECLARE @PRVRID ROWID = NULL, @CURRID ROWID = NULL
SELECT @CURRID = MIN(ROWID) FROM @ROWS
WHILE @CURRID IS NOT NULL BEGIN
MERGE @EMAILS AS DST
USING (SELECT * FROM @ROWS WHERE ROWID = @CURRID) AS SRC
ON SRC.ADDRESS = DST.ADDRESS
WHEN MATCHED THEN
UPDATE SET
DST.ALLIDS = DST.ALLIDS + ', ' + CONVERT(VARCHAR,ROWID),
DST.BODY = DST.BODY + '<i>'+CONVERT(VARCHAR,SRC.DATED,101)+' '
+CONVERT(VARCHAR,SRC.DATED,8)
+':</i> <b>'+SRC.SUBJECT+'</b>'+CHAR(13)+SRC.BODY
+' (Message ID '+CONVERT(VARCHAR,SRC.ROWID)+')'
+CHAR(13)+CHAR(13)
WHEN NOT MATCHED BY TARGET THEN
INSERT (ADDRESS, ALLIDS, BODY) VALUES (
SRC.ADDRESS,
CONVERT(VARCHAR,ROWID),
'<i>'+CONVERT(VARCHAR,SRC.DATED,101)+' '
+CONVERT(VARCHAR,SRC.DATED,8)+':</i> <b>'
+SRC.SUBJECT+'</b>'+CHAR(13)+SRC.BODY
+' (Message ID '+CONVERT(VARCHAR,SRC.ROWID)+')'
+CHAR(13)+CHAR(13));
SELECT @PRVRID = @CURRID, @CURRID = NULL
SELECT @CURRID = MIN(ROWID) FROM @ROWS WHERE ROWID > @PRVRID
END
DECLARE @MAILFROM VARCHAR(100) = system.getOption('MAILFROM'),
DECLARE @SMTPHST VARCHAR(100) = system.getOption('SMTPSERVER'),
DECLARE @SMTPUSR VARCHAR(100) = system.getOption('SMTPUSER'),
DECLARE @SMTPPWD VARCHAR(100) = system.getOption('SMTPPASS')
DECLARE @ADDRESS NAME, @BODY VARCHAR(MAX), @ADDL VARCHAR(MAX)
DECLARE @SUBJECT VARCHAR(1000) = 'Accumulated Emails from LIJSL'
DECLARE @PRVID NAME = NULL, @CURID NAME = NULL
SELECT @CURID = MIN(ADDRESS) FROM @EMAILS
WHILE @CURID IS NOT NULL BEGIN
SELECT @ADDRESS = ADDRESS, @BODY = BODY
FROM @EMAILS WHERE ADDRESS = @CURID
SELECT @BODY = @BODY + 'This is an automated message sent from an unmonitored mailbox.'+CHAR(13)+'Do not reply to this message; your message will not be read.'
SELECT @BODY =
'<style type="text/css">
* {font-family: Tahoma, Arial, Verdana;}
p {margin-top: 10px; padding-top: 10px; border-top: single 1px dimgray;}
p:first-child {margin-top: 10px; padding-top: 0px; border-top: none 0px transparent;}
</style>'
+ @BODY
exec system.LogIt @SUBJECT, @BODY
BEGIN TRY
exec system.SendMail @SMTPHST, @SMTPUSR, @SMTPPWD, @MAILFROM,
@ADDRESS, NULL, NULL, @SUBJECT, @BODY, 1
END TRY
BEGIN CATCH
DECLARE @EMSG NVARCHAR(2048) = 'system.EMAILQUEUE.AI:'+ERROR_MESSAGE()
SELECT @ADDL = 'TO:'+@ADDRESS+CHAR(13)+'SUBJECT:'+@SUBJECT+CHAR(13)+'BODY:'+@BODY
exec system.LogIt @EMSG,@ADDL
END CATCH
SELECT @PRVID = @CURID, @CURID = NULL
SELECT @CURID = MIN(ADDRESS) FROM @EMAILS WHERE ADDRESS > @PRVID
END
UPDATE system.EMAILQUEUE SET SENT = getdate()
FROM system.EMAILQUEUE E, @ROWS R WHERE E.ROWID = R.ROWID
END