如何使用UTF-8编码(codepage = 65001)将文件导入SQL Server

问题描述 投票:6回答:1

在挪威,我们有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>

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

sql-server powershell-v2.0
1个回答
0
投票

转而使用UTF16。这是SQL Server的本机NCHAR格式,并允许完全表示Unicode值。

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.