2

我正在使用 Powershell 执行插入语句并将字符串插入到数据库表中。我想插入的文本是从 HTTP 请求到 Confluence 的 REST API 并包含捷克语字符的。以下代码片段完成将数据插入数据库的工作

$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

数据库中的结果是一样的。我还能尝试什么?谢谢!

4

1 回答 1

3

也许问题如下(我无法亲自验证):

听起来您从 Confluence REST API 收到的是分解的Unicode 规范化形式(NFD)中的字符串 ,其中重音字符由两个代码点表示:基本字母(例如,e),然后是组合变音符号(例如, ́,组合尖锐的重音,U+0301 )

看起来 Oracle可能对这种分解的范式有问题,并且仅支持组合形式 (NFC),其中重音字母直接表示为单个代码点(例如,带有锐音 , 的拉丁é小写字母U+00E9

因此,您可以尝试使用以下方法将字符串转换为组合形式(NFC)String.Normalize()

$values[3].Normalize()  # Converts string $values[3] to NFC
于 2018-12-20T17:05:32.963 回答