Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как отправить с помощью sp_send_cdosysmail текст больше 8000 символов (вариант)  [new]
__vvp_
Member

Откуда: Санкт-Петербург
Сообщений: 1158
На форуме часто спрашивали как это осуществить, но конкретного ответа я не нашел.
В общем, у меня получилось и есть желание поделиться.

Не знаю насколько верно мое решение, но при создании sp_send_cdosysmail я параметру @Body указал тип text вместо nvarchar(4000).

CREATE PROCEDURE [dbo].[sp_send_cdosysmail]
   @From nvarchar(100) ,
   @To varchar(100) ,
   @Subject varchar(100)=" ",
   @Body text = " "--nvarchar(4000) =" "
AS
   Declare @iMsg int
   Declare @hr int
   Declare @source varchar(255)
   Declare @description varchar(500)
   Declare @output varchar(1000)

   EXEC @hr = sp_OACreate 'CDO.Message', @iMsg OUT

-- This is to configure a remote SMTP server.
-- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_schema_configuration_sendusing.asp
   EXEC @hr = sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/sendusing").Value','2'
--   EXEC @hr = sp_OASetProperty @iMsg, 'Configuration(cdoSendUsingMethod)', '2'
-- This is to configure the Server Name or IP address.
   EXEC @hr = sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/smtpserver").Value', '10.227.0.30'
--   EXEC @hr = sp_OASetProperty @iMsg, 'Configuration(cdoSMTPServerName)', '10.227.64.10'
-- Save the configurations to the message object.

-- Чтобы заставить слать письма по-русски
	EXEC @hr = sp_OASetProperty @iMsg, 'Fields.Item("urn:schemas:mailheader:content-type")', 'text/plain; charset=Windows-1251'
	EXEC @hr = sp_OASetProperty @iMsg, 'Fields.Item("urn:schemas:mailheader:content-transfer-encoding")', '8bit'
	EXEC @hr = sp_OASetProperty @iMsg, 'BodyPart.Charset', 'Windows-1251'

-- objMail.Fields.Item("urn:schemas:mailheader:content-type") = 'text/plain; charset=Windows-1251';
-- objMail.Fields.Item("urn:schemas:mailheader:content-transfer-encoding") = '8bit';
-- objMail.BodyPart.Charset = 'Windows-1251';

 EXEC @hr = sp_OAMethod @iMsg, 'Configuration.Fields.Update', null

-- Set the e-mail parameters.
   EXEC @hr = sp_OASetProperty @iMsg, 'To', @To
   EXEC @hr = sp_OASetProperty @iMsg, 'From', @From
   EXEC @hr = sp_OASetProperty @iMsg, 'Subject', @Subject

-- If you are using HTML e-mail, use 'HTMLBody' instead of 'TextBody'.
--   EXEC @hr = sp_OASetProperty @iMsg, 'HTMLBody', @Body
   EXEC @hr = sp_OASetProperty @iMsg, 'TextBody', @Body

   EXEC @hr = sp_OAMethod @iMsg, 'Send', NULL

   IF @hr <>0
     select @hr
     BEGIN
       EXEC @hr = sp_OAGetErrorInfo NULL, @source OUT, @description OUT
       IF @hr = 0
         BEGIN
           SELECT @output = '  Source: ' + @source
           PRINT  @output
           SELECT @output = '  Description: ' + @description
           PRINT  @output
         END
       ELSE
         BEGIN
           PRINT '  sp_OAGetErrorInfo failed.'
           RETURN
         END
     END

   EXEC @hr = sp_OADestroy @iMsg
GO

Далее нужно передать значение типа text в @Body. Делаю с помощью динамического SQL:

CREATE TABLE ##MsgText (MsgText text)
INSERT ##MsgText (MsgText) VALUES ('Что нибудь типа text')
DECLARE	
		@DataLen int,
		@SqlDec varchar(8000),
		@SqlStr varchar(8000),
		@SqlTot varchar(8000),
		@cnt int

SELECT @SqlDec = 'DECLARE',
	@SqlStr = '',
	@SqlTot = 'EXEC (''exec sp_send_cdosysmail @From = ''''mail@mail.ru'''', @To = ''''mail@mail.ru'''', @Subject = ''''Привет'''', @Body = '''''' + ',
	@cnt = 1

SELECT @DataLen = DATALENGTH (MsgText) / 8000 + 1 
FROM ##MsgText 
WHILE (@cnt <= @DataLen)
--BEGIN
	SELECT @SqlDec = @SqlDec + 
		CASE @cnt WHEN 1
			THEN ''
			ELSE ',' 
		END + CHAR(13) + '@Str' + CONVERT(varchar(10), @cnt) + ' varchar(8000) ', 
	@SqlStr = @SqlStr + CHAR (13) + 'SELECT @Str' + CONVERT(varchar(10), @cnt) + ' = SUBSTRING (MsgText, ' + CONVERT (varchar(30), (@cnt - 1) * 8000 + 1) + ', 8000) FROM ##MsgText ',
	@SqlTot = @SqlTot + 
		CASE @cnt WHEN 1 
			THEN '' 
			ELSE ' + ' 
		END + '@Str'+CONVERT(varchar(10), @cnt),
	@cnt = @cnt + 1
--END
SET @SqlTot = @SqlTot + ' + '''''''')'

-- PRINT @SqlDec 
-- PRINT '============================'
-- PRINT @SqlStr 
-- PRINT '============================'
-- PRINT @SqlTot 
-- PRINT '============================'

exec (@SqlDec + @SqlStr + @SqlTot)

DROP TABLE ##MsgText

27 май 05, 15:04    [1576700]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить