3

我正在varchar(500)从 SQL Server 2008 R2 数据库中读取一列,以通过固定宽度的文本文件导入 Redshift。

为了将记录下拉到一个固定宽度的文件中,我开始使用 a 一次StringBuilder写出一个文本块。我正在使用AppendFormat和对齐说明符来对齐不同的记录。在某些时候,每 400k 行一次,我会将 的内容StringBuilder写入 aStreamWriter以写入磁盘。

我注意到,当我尝试将文件加载到 Redshift 时,文本出现问题,由于额外的列,上传到 Reshift 失败,(列数超出了我的固定宽度规范所容纳的数量)。

当我StringBuilder针对常规字符串测试时,宽度与我希望它们匹配的宽度相匹配,500 个字符。

当我尝试将记录写入磁盘时,差异就出现了。WriteLineformat当我使用该StreamWriter对象将上述数据库列写入磁盘时,我一直遇到同样的问题。

数据库上的排序规则是SQL_Latin1_General_CP1_CI_AS. 我了解数据库中的字符串将数据库排序规则转换为 UTF-16。正如我上面执行的测试所述,我认为那里没有问题。我认为我遇到的问题是获取 UTF-16 格式的字符串并使用StreamWriter.

我可以期待数据库字段中的任何类型的字符,除了换行符或回车符。我非常有信心在使用 TSQL 函数LtrimRtrim.

编辑:以下是我在 Powershell 中使用的代码

$dw = new-object System.Data.SqlClient.SqlConnection("<connection string details>")
$dw.open()
$reader = (new-object System.Data.SqlClient.Sqlcommand("select email from emails",$dw)).ExecuteReader()
$writer = new-object system.IO.StreamWriter("C:\Emails.txt",[System.Text.Encoding]::UTF8)
while($reader.read())
{
    $writer.writelineformat("{0,-500}",$reader["email"])
}
$writer.close()
$reader.close()

显然,我不会向您提供我的连接字符串或表命名约定的详细信息。

编辑:我包括 AWS Redshift 文章,该文章解释了只能使用 UTF-8 编码将数据导入 Redshift。

http://docs.aws.amazon.com/redshift/latest/dg/t_preparing-input-data.html

编辑:我能够通过

get-content -encoding utf8

文件内的内容绝对是 UTF-8 正确的。所有的行结尾都在里面。似乎我的主要问题是 Redshift 将多字节字符用于固定宽度的文件。

4

2 回答 2

3

我怀疑这个问题是由于StreamWriter默认使用 UTF-8 造成的,因此在某些情况下,您会得到双字节字符,因为 utf-8 是可变宽度。

尝试使用unicode,它将匹配您的数据库编码,StreamWriter具有支持编码的重载。

于 2013-11-08T14:44:18.943 回答
1

只是为了让看到这个的人都明白。我的问题真的是红移。我注意到的一件事是该服务似乎存在处理固定宽度文件的问题。这似乎是亚马逊特有的,因为运行 Redshift 的底层系统是 ParAccel。过去我在使用 Fixedwidth 文件时遇到过问题。我已经能够确认 Redshift 在 S3 Copy 命令的固定宽度版本中接受多字节字符存在问题。

于 2013-11-14T02:36:01.730 回答