Почему острый отделяется от своего базового письма при вставке в базу данных оракула через Powershell?
Я использую 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, он также выглядит нормально.
Но когда я вижу результат в базе данных, это выглядит следующим образом:
Таким образом, все буквы в порядке, за исключением того, что острые буквы отделены от своей основной буквы. Я пробовал разные кодировки в 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 ответ
Возможно, проблема в следующем (я не могу лично проверить это):
Похоже, что то, что вы получаете от Confluence REST API, - это строки в разложенной форме нормализации Unicode (NFD), в которой акцентированные символы представлены двумя кодовыми точками: базовой буквой (например, e
), сопровождаемый объединяющим диакритическим знаком (например, ́
сочетающий острый акцент , U+0301
)
И похоже, что Oracle, возможно, испытывает проблемы с этой разложенной нормальной формой и поддерживает только составную форму (NFC), где акцентированные буквы имеют прямое представление в виде единой кодовой точки (например, é
латинская строчная с острым , U+00E9
),
Поэтому вы можете попытаться преобразовать строки в составленную форму (NFC), используя String.Normalize()
метод:
$values[3].Normalize() # Converts string $values[3] to NFC