What encoding string UTF8 or WIN1251

Пример, как определить кодировку строки UTF8 или WIN1251?

with t as
(select 'Текст в кодировке UTF8' filename from dual union
select 'Текст в кодировке WIN1251' filename from dual union
select 'Text does not contain cyrilic charcters' filename from dual)
select filename,
case
    when not regexp_like(asciistr(convert(filename, 'cl8mswin1251')), '\FFFD') then
        case
            when regexp_like(convert(filename, 'cl8mswin1251', 'utf8'),'[а-яА-Я]') then 'UTF8'
            else 'WIN1251'
        end
        else 'WIN1251'
end ENCODE from t
order by 2;

FILENAME                                  ENCODE
----------------------------------------- -------
Текст РІ РєРѕРґРёСЂРѕРІРєРµ UTF8     UTF8   
Текст в кодировке WIN1251                 WIN1251
Text does not contain cyrilic charcters   WIN1251

Теперь дополним пример конвертацией текста UTF8 в WIN1251:

with t as
(select 'Текст в кодировке UTF8' filename from dual union
select 'Текст в кодировке WIN1251' from dual union
select 'Text does not contain cyrilic charcters' from dual)
select
encode,
case
    when ENCODE = 'WIN1251' then filename
    else convert(filename, 'cl8mswin1251', 'utf8')
end decode_filename
from(
select filename,
case
    when not regexp_like(asciistr(convert(filename, 'cl8mswin1251')), '\FFFD') then
        case
            when regexp_like(convert(filename, 'cl8mswin1251', 'utf8'),'[а-яА-Я]') then 'UTF8'
            else 'WIN1251'
        end
        else 'WIN1251'
end ENCODE from t)
order by 2;
                                      
ENCODE    DECODE_FILENAME
--------  -----------------------------------------
UTF8      Текст в кодировке UTF8
WIN1251   Текст в кодировке WIN1251
WIN1251   Text does not contain cyrilic charcters                                                      

 

 

Реклама

Convert mail message from utf8 to windows-1251

Если вы с помощью PL\SQL делаете разбор почтовых сообщений (стандарта MIME) и получаете атрибуты (тема, тело сообщения, имена вложенных файлов и т.п.), Вы можете столкнуться с ситуацией, когда значение некоторых атрибутов дает подобный результат:

=?utf-8?B?cGxhbV/QutCw0Lot0YLQviDRgtCw0LpfMi5qcGc=?=

В моем случае я получал имя файла вложенного в письмо. Данное письмо я считывал из почтового ящика при помощи пакета MAIL_CLIENT.
Как оказалось когда имя файла во вложении было на латинице, то я его получал без проблем, но когда в имени файла содержались символы кириллицы, он кодировался в формат заголовка MIME с кодировкой UTF8.У Oracle для этих случаев есть пакет UTL_ENCODE, который позволяет кодировать и декодировать данные для почтовых сообщений.
В итоге написав следующую конструкцию, я решил проблему с кириллицей в имени файла:

file_name := case
when filename like '=?utf-8?%' then utl_encode.mimeheader_decode(filename)
else filename
end;

где, filename - это значение атрибута - имя вложенного файла в письме.
А условие case нужно для того, чтобы выполнять декодирование строк формата заголовка MIME в UTF8,
и не обрабатывать их, если имя содержит только латиницу.

В итоге я получил вместо:
=?utf-8?B?cGxhbV/QutCw0Lot0YLQviDRgtCw0LpfMi5qcGc=?=
нужное мне значение имени файла:
plam_как-то так_2.jpg

Для проверки:

select utl_encode.mimeheader_decode('=?utf-8?B?cGxhbV/QutCw0Lot0YLQviDRgtCw0LpfMi5qcGc=?=')
VAL from dual;

VAL                                                                             
----------------------
plam_как-то так_2.jpg  

Write the result of SQL-query in file with encoding UTF-8 without BOM

Скрипт позволяет выгрузить результат SQL-запроса (MS SQL Server) в текстовый файл с разделителями в кодировке UTF-8 без BOM.

Dim oSource
Dim oDatabase
Dim oUser
Dim oPassword
Dim conn
Dim cmd
Dim rs
Dim fs
Dim arr
Dim textStream
Dim FileName
Dim strLine, Str
Dim Res
Dim sep
Dim i
Dim dblQuate

'Enter settings for connecting to MS SQL database
oSource = "mssqlsrv"
oDatabase = "hwiproducts"
oUser = "hwiuser"
oPassword = "*******"

Set conn = CreateObject("ADODB.Connection")
conn.Open "Provider=SQLOLEDB;Data Source=" _
    & oSource & ";Trusted_Connection=Yes;Initial Catalog=" _
    & oDatabase & ";User ID=" & oUser & ";Password=" & oPassword & ""

Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn

'Place your SQL-Query
cmd.CommandText = "SELECT TYPENAME, " _
                 & "MDNAME, " _
                 & "SN, " _
                 & "STRIHCODE, " _
                 & "VENDOR, " _
                 & "convert(varchar(20), INDEMNITYD, 120) INDEMNITYD, " _
                 & "convert(varchar(20),GUARANT,120) GUARANT, " _
                 & "DEP " _
                 & "FROM [hwiproducts].[dbo].[productstores]" _
                 & "WHERE TYPEEQU = 'Printers'"

'Execute your SQL-Query
Set rs = cmd.Execute
 
'Specify the full path to the file to which we write the query result
FileName = "d:\PLANTRACE\HWI\Printers.csv"
 
Set fs = CreateObject("Scripting.FileSystemObject")

'Check the existence of the file and delete it (if necessary)
If fs.FileExists(FileName) Then
   fs.DeleteFile(FileName)
End If

Set textStream = fs.OpenTextFile(FileName, 8, True)

'Specifies the separator
sep = ","

Do Until rs.EOF
    
    'Count the number of fields
    ColCount = rs.Fields.Count - 1
    
    For i = 0 To ColCount
        'Add double quotes to values (if necessary)
        dblQuate = """"& rs(rs.Fields(i).Name) &""""
        
        'Form a string to write to the file
        strLine = strLine & sep & dblQuate
        
        If i = ColCount Then
            
            'Separator to remove from the beginning of the string
            Str = Replace(strLine,",","",1,1)
            
            'Convert string to UTF-8 without BOM and write it in file
            Res = StrConvert (Str, "Windows-1251", "UTF-8")
            textStream.WriteLine Res
            
            'When a string is writed then clean it
            strLine = ""
        End If
    Next
    
    'Next row from result query
    rs.MoveNext
Loop

'Close stream, command and connecting
textStream.Close
rs.Close
conn.Close

Function StrConvert(Text, FromCharset, ToCharset)
'What's: converts the string in encoding UTF8 without BOM
Dim Stream

Set Stream = CreateObject("ADODB.Stream")
    Stream.Type = 2
    Stream.Mode = 3
    Stream.Open
    Stream.Charset = ToCharset
    Stream.WriteText Text
    Stream.Position = 0
    Stream.Charset = FromCharset
    BOM = Stream.ReadText(3)

'Skip BOM bytes
If AscB(MidB(BOM, 1, 1)) = 239 And AscB(MidB(BOM, 2, 1)) = 187 _
                             And AscB(MidB(BOM, 3, 1)) = 191 Then
    Stream.Position = 3
 Set fOut = CreateObject("adodb.stream")
    fOut.Type = 2
    fOut.Mode = 3
    fOut.Open
    fOUT.WriteText Text
    StrConvert = fOUT.ReadText
Else
    StrConvert = Stream.ReadText
End If
 
End Function