Mon VARCHAR(MAX) champ est le coiffage de lui-même à 4000; ce qui donne?

J'ai une table dans l'un de mes bases de données, qui est une file d'attente d'e-mails. E-mails à certaines adresses obtenir accumulés en un seul e-mail, qui est réalisée par la procédure stockée. Dans la procédure stockée, j'ai une variable de table que j'utilise pour construire le cumul des corps des e-mails, puis faire une boucle pour envoyer chaque e-mail. Dans ma table var, j'ai mon corps de colonne définie comme VARCHAR(MAX), car il pourrait y avoir un certain nombre de courriels actuellement accumulé une adresse e-mail. Il semble cependant que même si ma colonne est définie comme VARCHAR(MAX) elle se comporte comme si elle était VARCHAR(4000) et est tronquer les données qui vont dans ce, bien qu'il ne PAS de jeter des exceptions, c'est juste silencieusement arrêts de la concaténation de plus de données après 4000 caractères.

L'instruction MERGE est là que c'est la construction de la accumulé email en @e-MAILS.CORPS, qui est le champ qui est à tronquer lui-même à 4000 caractères.

MODIFIER

J'ai mis à jour mon instruction MERGE dans une tentative de jeter le tout attribué chaîne de type VARCHAR(MAX), mais il est toujours silencieusement troncature à 4000 caractères... voici ma nouvelle FUSION:

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)
        )
    );

FIN MODIFIER

Ci-dessous le code de ma procédure stockée...

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
Veuillez voir ma mise à jour... vous avez une nvarchar sur la droite qui est de la conversion de type varchar(max), nvarchar(4000) implicitement
Serait habillage de l'ensemble du membre de droite de l'expression dans un CONVERT(VARCHAR(MAX), <expression>) pour ma mise à jour à ne pas prendre soin de cela?
Type de données de priorité...
La seule chose que je vois qui n'est pas explicitement converti à VARCHAR(MAX) est la traduction littérale des chaînes de caractères comme '<i>'. Ne littéraux aller en tant que NVARCHAR? La SRC.<champs> sont tous convertis à VARCHAR, et le CHAR de la fonction renvoie un type CHAR.

OriginalL'auteur eidylon | 2010-03-23