Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / CDO.Message - настроить кодировку либо тело письма брать из файла / 16 сообщений из 16, страница 1 из 1
04.12.2006, 14:02
    #34174752
ilya_er
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Проблема в следующем: есть процедура, она формировала отчет-напоминание и отсылала по почте. Использовала xp_smtp_sendmail (у меня SQL2000 ). Отчет выгружался с помощью bcp в файл и процедура брала текст из файла. Тело отчета - в html. xp_smtp_sendmail. Проблем не было.

Через некоторое время на smtp-сервере установили запрет на отсылку без авторизации. Пришлось переползти на CDO.Message . Отсылка заработала, но возникла проблема:

Воспроизвести на серверной стороне загрузку тела письма из файла не удалось. Стал вызывать процедуру через exec + конкатенация строк (как тут ).
Текст процедуры, отпраляющей почту :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
IF EXISTS (SELECT name 
	   FROM   sysobjects 
	   WHERE  name = N'cp_send_cdosysmail'
	   AND 	  type = 'P')
    DROP PROCEDURE cp_send_cdosysmail
GO

/*********************************************************************
См. ссылку CDOSYS objects по следующему адресу MSDN Web site:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_messaging.asp
***********************************************************************/

CREATE PROCEDURE dbo.cp_send_cdosysmail
@SMTPServerName VARCHAR( 100 ), 
@username varchar( 100 ),
@password varchar( 100 ),
@Charset varchar( 10 )='koi8-r', --'unicode', 

@To VARCHAR( 100 ),
@From VARCHAR( 100 ),
@Subject NVARCHAR( 100 )=" ",
@Body ntext=" ",
@CC VARCHAR( 100 )=NULL,
@BCC VARCHAR( 100 )=NULL
AS
SET NOCOUNT ON
DECLARE @iMsg INTEGER, @hr INTEGER, @source VARCHAR( 255 ), @description VARCHAR( 500 ), @output VARCHAR( 1000 ),
  @iFile integer, @authtype int, @res int

 set @authtype =  1  -- clear text; OAbASIC
--SET @SMTPServerName='192.168.1.3' -- Указываем имя или IP-адрес SMTP-сервера, например, 'localhost'

 if @Charset is null
  set  @Charset='koi8-r'
  --set @Charset='unicode'

EXEC @hr=sp_OACreate 'CDO.Message', @iMsg OUT
-- Конфигурируем удалённый SMTP-сервер:
-- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_schema_configuration_sendusing.asp
-- 1=значит отсылка сообщения будет осуществляться через локальный SMTP-сервер
-- 2=значит отсылка сообщения будет осуществляться через SMTP-сервер домена
EXEC @hr=sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/sendusing").Value','2'

EXEC @hr=sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/smtpserver").Value', @SMTPServerName
EXEC @hr=sp_OAMethod @iMsg, 'Configuration.Fields.Update', null -- Устанавливаем конфигурацию message-объекта

EXEC @hr=sp_OASetProperty @iMsg, 'To', @To
EXEC @hr=sp_OASetProperty @iMsg, 'From', @From
EXEC @hr=sp_OASetProperty @iMsg, 'CC', @CC
EXEC @hr=sp_OASetProperty @iMsg, 'BCC', @BCC
EXEC @hr=sp_OASetProperty @iMsg, 'Subject', @Subject

-- !!!! далее - война с кодировкой
EXEC @hr = sp_OASetProperty @iMsg, 'Configuration.fields("urn:schemas:mailheader:content-language").Value',  @Charset

EXEC @hr=sp_OASetProperty @iMsg, 'HTMLBodyPart.Charset', @Charset
EXEC @hr=sp_OASetProperty @iMsg, 'HTMLBodyPart.CODEPAGE',  20866 




if not (@username is null) and not (@password is null) 
begin
  EXEC @hr=sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate").Value', @authtype -- тип аутентификации
  EXEC @hr=sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/sendusername").Value', @username  -- имя пользователя
  EXEC @hr=sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/sendpassword").Value', @password  -- пароль
  EXEC @hr=sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/smtpaccountname").Value', @username  -- имя пользователя

end

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


-- Если указан НЕкорректный e-mail адрес, то будет возвращён код 2147220977.
-- Если указан НЕкорректное имя MAIL Server-а, то будет возвращён код -2147220973
/*
IF @hr <>0
SELECT @hr
BEGIN
*/
EXEC @hr = sp_OAGetErrorInfo NULL, @source OUT, @description OUT
set @res = @hr
/*
IF @hr=0
BEGIN
SELECT @output = ' Источник: ' + @source
PRINT @output
SELECT @output = ' Описание: ' + @description
PRINT @output
END
ELSE
BEGIN
PRINT ' p_OAGetErrorInfo ошибка!'
print @hr
END
--END
*/

EXEC @hr = sp_OADestroy @iMsg
RETURN @res
go


В заголовке html кодировка так же указывается.
Кодировка устанавливается (комментарий, помеченный -- !!!! в коде). Т.к. она одна, case для определения кодовой страницы писать я не стал.
Проблема в следующем : физически письмо приходит в кодировке koi-8. При вызове формирующей процедуры из QA все работает. При вызове процедуры через job c вероятностью примерно 40% приходят знаки вопроса, в остальных случаях письма приходят корректные.

В качестве клиента используется в компании The Bat ! и менять это не хотелось бы.

Т.к. штатный запуск - раз в сутки, хотелось бы это побороть...

Пример с отдельным OLE-объектом для зачитывания тела письма из файла на vbscript я нашел, но - непонятно, можно ли получить ответ от одной sp_OASetProperty и скормить его другой... Хотя - тогда тело было бы в unicode, как bcp формирует, и проблема была бы решена.
...
Рейтинг: 0 / 0
04.12.2006, 18:23
    #34175769
ilya_er
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Главное - если бы всегда приходили знаки вопроса, я бы понял - неправильно настроен объект, а тут - то приходит корректный текст, то - некорректный... и именно из джоба...
...
Рейтинг: 0 / 0
07.12.2006, 13:09
    #34183020
ilya_er
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
В общем, как всегда. Стоило весь текст, включая текст динамического sql перевести в nvarchar/ntext - и все заработало. Кстати, оказалось, что exec() нормально переваривает nvarchar .
...
Рейтинг: 0 / 0
07.12.2006, 13:43
    #34183184
ilya_er
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Поторопился... все равно, как оказалось, через раз знаки вопроса приходят.Заметил, что в "хороших" письмах в служебной информации сабжект письма выглядит так :
Код: plaintext
1.
Subject: =?koi8-r?B?7sXPwsjPxMnNz9PU2CDBy9TVwczJ2sHDyckg0NLBytMtzMnT1M/X?=

а в плохих - так :
Код: plaintext
1.
Subject: ????????????? ???????????? ?????-??????

То есть, он через раз понимает, что кодировка ?koi8-r? , хотя сообщение формирует одна и та же процедура.
Тест проводился установкой отправки письма через job раз в минуту в течение 10 минут.

Неужели ни у кого никаких мыслей нет ?
...
Рейтинг: 0 / 0
15.12.2006, 12:59
    #34202741
ilya_er
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Ладно, раз все молчат, другой вопрос - из какого файла MSSQL 2000 берет класс CDO.Message ?

Следы на msdn.com ведут к cdo.dll , библиотеки такой у меня на машине нет, а CDO.Message работает.

И, для верности, @@version
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
-- тестовый сервер
Microsoft SQL Server   2000  -  8 . 00 . 2039  (Intel X86) 
	May   3   2005   23 : 18 : 38  
	Copyright (c)  1988 - 2003  Microsoft Corporation
	Developer Edition on Windows NT  5 . 1  (Build  2600 : Service Pack  2 )

-- рабочий сервер
Microsoft SQL Server   2000  -  8 . 00 . 760  (Intel X86) 
	Dec  17   2002   14 : 22 : 05  
	Copyright (c)  1988 - 2003  Microsoft Corporation
	Standard Edition on Windows NT  5 . 0  (Build  2195 : Service Pack  4 )


На тестовом стоит SP4. На рабочем - SP3, кроме моей системы там стоит еще сторонняя, поэтому я бы с радостью не стал ставить туда SP4, если это возможно. Не уверен, как эта система себя поведет.
...
Рейтинг: 0 / 0
15.12.2006, 16:05
    #34203686
ilya_er
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Нашел пример задания параметров , выставил
Код: plaintext
'Configuration.Fields.Update'
в нескольких местах... попытался создавать явно части сообщения... все равно не работает..... максимальный результат - 70%... Ну хоть у кого-нибудь мысли есть ?
...
Рейтинг: 0 / 0
15.12.2006, 20:49
    #34204481
Ёжик`
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
cdosys.dll
...
Рейтинг: 0 / 0
15.12.2006, 21:26
    #34204509
Lepsik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
ilya_erЛадно, раз все молчат, другой вопрос - из какого файла MSSQL 2000 берет класс CDO.Message ?

Следы на msdn.com ведут к cdo.dll , библиотеки такой у меня на машине нет, а CDO.Message работает.



быть такого не может. CDO - это API аутлука для работы с Exchange. То есть у вас должен быть настроен профайл, откуда все установки (в том числе и кодировки) по умолчанию и должны браться.
...
Рейтинг: 0 / 0
15.12.2006, 21:42
    #34204527
Ennor Tiegael
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Были аналогичные проблемы. Пришлось написать standalone EXE на VB6, который и занимается собственно отправкой. В нем это выглядит примерно так (вкратце):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
Private Sub SendMail()
' CDO Objects
Dim iBp As CDO.IBodyPart
Dim Msg As CDO.Message
' Init root CDO object
Set Msg = New CDO.Message
With Msg
  .AutoGenerateTextBody = False
  .From = "from"
  .To = "to"
End With
' !!! Get correct interface from this object
Set iBp = Msg
' !!! Set some content-related properties
With iBp
  .ContentMediaType = cdoTextHTML
  .ContentTransferEncoding = cdo8bit
  .Charset = cdoUTF_8
End With
' Set sending properties
With Msg.Configuration.Fields
  .Item(cdoSendUsingMethod) = cdoSendUsingPort
  .Item(cdoSMTPServer) = "smtp.server"
  .Item(cdoSMTPConnectionTimeout) =  60 
  .Item(cdoSMTPAuthenticate) = cdoBasic
  .Item(cdoSendUserName) = "name"
  .Item(cdoSendPassword) = "password"
  .Update
End With
Msg.HTMLBody = ... ' Some HTML code
' Get subject from HTML title
Msg.Fields(cdoSubject) = Doc.Title
Msg.Fields(cdoXMailer) = App.Title
Msg.Fields.Update
' Send!
Msg.Send
End Sub
Прикол в том, что нужно от переменной Msg взять интерфейс IBodyPart и манипулировать уже с его свойствами. Как это сделать в VBScript и можно ли в нем такое сделать вообще - не знаю, вроде как нет (из-за отсутствия типизации). Так или иначе, но ключевым, кажется, оказалось свойство IBodyPart.Charset.
...
Рейтинг: 0 / 0
15.12.2006, 21:47
    #34204534
Ennor Tiegael
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
LepsikCDO - это API аутлука для работы с Exchange. То есть у вас должен быть настроен профайл, откуда все установки (в том числе и кодировки) по умолчанию и должны браться.
Вы путаете CDO и MAPI. В последнем случае в системе действительно должен быть установлен почтовый клиент и настроена учетка почты.
Что же касается CDO, то эта библиотека входит в состав винды, начиная с W2K и ничьим API, насколько я помню, не является. В составе MS Exchange идет специализированная версия этой библы, да, но разница между этими версиями не имеет никакого отношения к данному вопросу.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
17.08.2012, 23:04
    #37921452
-Iriska-
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
ilya_er,

нужно задать кодировку в свойстве объекта CDO.Mesage:

.BodyPart.Charset = "windows-1251"
...
Рейтинг: 0 / 0
18.08.2012, 02:30
    #37921503
Mnior
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
-Iriska- , уже почти 6 лет прошло. Думаю им уже это не надо. =)

Блин, а в мире столько готовых стандартных OpenSource утилит аля SendMail, что городить огород и тонны и месиво кода просто преступление.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
24.04.2014, 04:53
    #38623899
ЗууеВ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Мне помогло. Спасибо 8-)
...
Рейтинг: 0 / 0
06.07.2014, 12:06
    #38688812
dolly_ev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Mnior -Iriska- , уже почти 6 лет прошло. Думаю им уже это не надо. =)
Прошло еще 2 года и мне тоже помогло :-)) Спасибо!
...
Рейтинг: 0 / 0
09.06.2015, 10:50
    #38979874
Алекс2014
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Помогли такие строки
-- Установка кодировки для текста
--EXEC @hr = sp_OAGetProperty @iMsg, 'TextBodyPart', @BodyPart out
--EXEC @hr = sp_OASetProperty @BodyPart, 'Charset', 'windows-1251'

-- Установка кодировки для html
---- для html body
EXEC @hr = sp_OAGetProperty @iMsg, 'HTMLBodyPart', @BodyPart out
EXEC @hr = sp_OASetProperty @BodyPart, 'Charset', 'windows-1251'
---- для html header
EXEC @hr = sp_OAGetProperty @iMsg, 'BodyPart', @BodyPart out
EXEC @hr = sp_OASetProperty @BodyPart, 'Charset', 'windows-1251'
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
27.02.2018, 12:12
    #39607767
GigaWatt
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
CDO.Message - настроить кодировку либо тело письма брать из файла
Класс! Прошло ещё 4 года, а тема не перестаёт помогать!
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / CDO.Message - настроить кодировку либо тело письма брать из файла / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]