6

在挪威,我们有 3 个非常烦人的角色 æøå,它们会制造各种问题。自 sql server 2008 以来,Microsoft 决定不支持代码页 65001。我找到了一个可管理的解决方案,可以解决使用 OPENROWSET(BULK) 将 UTF-8 文件导入 sql server 并保留 æøå 令牌的问题。

我创建了一个 powershell 脚本,它使用 StreamReader 和 StreamWriter 将文件从 UTF-8 转换为默认编码 ANSI。

$filename = "C:\Test\UTF8_file.txt"
$outfile = "C:\Test\ANSI_file.txt"
$reader = new-object System.IO.StreamReader($filename, [System.Text.Encoding]::GetEncoding(65001))
$stream = new-object System.IO.StreamWriter($outfile, $false, [System.Text.Encoding]::Default)

我在同一过程中剥离了第一行的文件,即标题行。

$i=1
while(($line = $reader.ReadLine()) -ne $null) {
    if($i -gt 1) {
        $stream.WriteLine($line)
    }
    $i++
}
$reader.Close()
$stream.Close()

然后我可以使用 OPENROWSET 将 ANSI 文件导入 sql server 并在此过程中操作数据。使用代码页 1252,它等于 danish_norwegian 排序规则。

    insert into SomeDatabase.dbo.SomeTable
SELECT [companynumber]
, case [role] when 'Styreformann' then 'Styreleder' when 'Styrets leder' then 'Styreleder' else rolle end as 'role'
, case [representant] when 'Y' then '1' else '0' end as 'representant'
, left((RIGHT('0000'+ CONVERT(VARCHAR,postnr),5)),4) end as 'postnr' 
, income*1000 as income
, null as person2id 
FROM OPENROWSET( BULK 'C:\Test\ANSI_file.txt', 
FORMATFILE = 'C:\Test\FormatBulkInsert_file.xml'
, CODEPAGE =1252
, ROWS_PER_BATCH = 50000    
) as v 

这种方法确保挪威代币正确显示。格式文件如下所示:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <RECORD>
    <FIELD ID="1" xsi:type="CharTerm" TERMINATOR=';"' />
    <FIELD ID="2" xsi:type="CharTerm" TERMINATOR='";"' />
    <FIELD ID="3" xsi:type="CharTerm" TERMINATOR='";"' />
    <FIELD ID="4" xsi:type="CharTerm" TERMINATOR='";' />
    <FIELD ID="5" xsi:type="CharTerm" TERMINATOR=';' />
    <FIELD ID="6" xsi:type="CharTerm" TERMINATOR='\n' />
  </RECORD>
  <ROW>
    <COLUMN SOURCE="1" NAME="companynumber" xsi:type="SQLINT"/>
    <COLUMN SOURCE="2" NAME="role" xsi:type="SQLNVARCHAR"/>
    <COLUMN SOURCE="3" NAME="representant" xsi:type="SQLBIT"/>
    <COLUMN SOURCE="4" NAME="postnr" xsi:type="SQLNVARCHAR"/>
    <COLUMN SOURCE="5" NAME="income" xsi:type="SQLDECIMAL"/>
    <COLUMN SOURCE="6" NAME="person2id" xsi:type="SQLINT"/>
  </ROW>
</BCPFORMAT>

希望这对其他人有帮助,因为在找到解决此问题的方法之前,我花了很多时间进行谷歌搜索。

4

1 回答 1

0

改为转换为 UTF16。那是 SQL Server 的本机 NCHAR 格式,并且允许 Unicode 值的完整表示。

要完成这项工作,您必须在格式文件中指定 SQLNCHAR 或 SQLNVARCHAR,并注意以下警告:

对于要使用 Unicode 字符数据文件的格式文件,所有输入字段都必须是 Unicode 文本字符串(即,固定大小或以字符结尾的 Unicode 字符串)。

另一种方法是将其加载为二进制数据并使用该CONVERT函数将其从转换VARBINARYNVARCHAR(UTF-16),然后转换为所需的代码页为VARCHAR.

于 2013-02-28T15:09:42.400 回答