Почему острый отделяется от своей основной буквы при вставке в базу данных оракула через Powershell? - PullRequest
0 голосов
/ 20 декабря 2018

Я использую Powershell для выполнения оператора вставки и вставки строки в таблицу базы данных.Текст, который я хочу вставить, я получаю из HTTP-запроса в API REST Confluence и содержит чешские символы.Следующий фрагмент кода выполняет вставку данных в базу данных

$DAOControllerClass | Add-member -MemberType ScriptMethod -Name Get-DataBaseConnection -Value {
[OutputType([System.Data.OracleClient.OracleConnection])]

$username = $this.username
$password = $this.password
$data_source = $this.data_source 

log("Executing Get-DataBaseConnection")

$connection_string = "User Id=$username;Password=$password;Data Source=$data_source"
$con = New-Object System.Data.OracleClient.OracleConnection($connection_string)
try {
    $con.Open()
} catch {
    throw "Could not open database connection"
}
log("Connectiong opened")
return $con
}

$DAOControllerClass | Add-Member -MemberType ScriptMethod -Name Update-CNFLPageIntoOldWorld -Value {
param(
    [Parameter(Mandatory=$true)][String[]]$values
)
log("Executing Update-CNFLPageIntoBaseLayer")


try{
    $con = $this.'Get-DataBaseConnection'()

    $command             = $con.CreateCommand()
    $command.Connection  = $con
    $command.CommandText = [IO.File]::ReadAllText(".\Database queries\Data dictionary - Core layer queries\Update_cnfl_page_old_world.sql")

    $null = $command.Parameters.Add("cnfl_page_id", $values[0])
    $null = $command.Parameters.Add("label", $values[1]) 
    $null = $command.Parameters.Add("business_pojem_html", $values[2]) 
    $null = $command.Parameters.Add("popis_html",$values[3]) # The issue is with $values[3]

    $null = $command.ExecuteNonQuery()

    log("The cnfl page with the id: " + $values[0] + " got updated in the table confluence_page_old_world")
} catch {
    throw (“Database Exception: " + $con.ConnectionString + ": " + $_.Exception.ToString())
} finally{
    if ($con.State -eq ‘Open’) { 
        $con.close() 
        $command.Dispose()
    }
}

}

Теперь текст, который я передаю в качестве параметра при загрузке со страницы Confluence, выглядит следующим образом: «Reportingové statusy a příchody / odchody klientů."

Когда я печатаю этот текст в Powershell, все выглядит нормально.Все буквы представлены так, как они должны быть.Когда я отлаживаю этот код и вижу, какой текст назначен $ command.CommandText, он также выглядит нормально.

Но когда я вижу результат в базе данных, он выглядит следующим образом:

Result row in Database

Так что все буквы в порядке, за исключением того, что акуты отделены от егобазовое письмо.Я пробовал разные кодировки в powershell, я пытался изменить настройки NLS в базе данных.Я также пытался записать в файл .txt, закодировать его с помощью utf-8, с использованием Unicode и ISO / IEC 8859-2 только для чтения его из файла, но это также не сработало.

Единственноето, что работает, это когда я жестко кодирую текст в Powershell следующим образом:

$null = $command.Parameters.Add("popis_html","Reportingové statusy a příchody/odchody klientů.")

Тогда я получаю ожидаемый результат.Поэтому мне кажется, что при передаче строки в качестве аргумента происходит какое-то преобразование или кодирование, но я понятия не имею, что это может быть, потому что буквы на самом деле представляются, речь идет только об акутах.У меня есть следующие настройки кодирования в Powershell

IsSingleByte      : True
BodyName          : iso-8859-2
EncodingName      : Central European (Windows)
HeaderName        : windows-1250
WebName           : windows-1250
WindowsCodePage   : 1250
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : True
CodePage          : 1250

И следующие nls_session_parameters

NLS_LANGUAGE    CZECH
NLS_TERRITORY   CZECH REPUBLIC
NLS_CURRENCY    Kč
NLS_ISO_CURRENCY    CZECH REPUBLIC
NLS_NUMERIC_CHARACTERS  ,.
NLS_CALENDAR    GREGORIAN
NLS_DATE_FORMAT DD.MM.RR
NLS_DATE_LANGUAGE   CZECH
NLS_SORT    CZECH
NLS_TIME_FORMAT HH24:MI:SSXFF
NLS_TIMESTAMP_FORMAT    DD.MM.RR HH24:MI:SSXFF
NLS_TIME_TZ_FORMAT  HH24:MI:SSXFF TZR
NLS_TIMESTAMP_TZ_FORMAT DD.MM.RR HH24:MI:SSXFF TZR
NLS_DUAL_CURRENCY   Kč
NLS_COMP    BINARY
NLS_LENGTH_SEMANTICS    BYTE
NLS_NCHAR_CONV_EXCP FALSE

Я попытался установить кодировку Powershell в Unicode с этой строкой

$OutputEncoding = [System.Text.Encoding]::Unicode

Результатв базе было то же самое.Что еще я мог попробовать?Спасибо!

1 Ответ

0 голосов
/ 20 декабря 2018

Возможно, проблема заключается в следующем (я не могу лично проверить это):

Похоже, что вы получаете от Confluence REST API строки в разложенный Форма нормализации Unicode (NFD) , в которой символы с акцентом представлены двумя кодовыми точками : основание буква (например, e), за которой следует диакритический знак (например, ́, , объединяющий острыйaccent , U+0301)

И похоже, Oracle возможно испытывает проблемы с этой разложенной нормальной формой и поддерживает только составная форма (NFC) , где акцентированные буквы имеют прямое представление в виде одиночной кодовой точки (например, é, латинской маленькой буквыс острыми , U+00E9 ),

Следовательно, вы можете попытаться преобразовать строки в составную форму (NFC), используяString.Normalize() метод :

$values[3].Normalize()  # Converts string $values[3] to NFC
...