Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将Apple EPF Unicode数据批量插入SQL Server 2012_C#_Sql Server_Unicode_Bulkinsert - Fatal编程技术网

C# 将Apple EPF Unicode数据批量插入SQL Server 2012

C# 将Apple EPF Unicode数据批量插入SQL Server 2012,c#,sql-server,unicode,bulkinsert,C#,Sql Server,Unicode,Bulkinsert,我正在尝试构建一个应用程序,将Apple EPF提要数据导入SQL Server 2012实例。数据以平面文件的形式提供,平面文件使用CHAR(1)字段分隔符和CHAR(2)加上换行符(CHAR(10))作为行分隔符。因此,简化的3字段行如下所示: field1value[char(1)]field2value[char(1)]field3value[char(2)][linefeed] field1value[char(1)]field2value[char(1)]field3value[ch

我正在尝试构建一个应用程序,将Apple EPF提要数据导入SQL Server 2012实例。数据以平面文件的形式提供,平面文件使用CHAR(1)字段分隔符和CHAR(2)加上换行符(CHAR(10))作为行分隔符。因此,简化的3字段行如下所示:

field1value[char(1)]field2value[char(1)]field3value[char(2)][linefeed]
field1value[char(1)]field2value[char(1)]field3value[char(2)][linefeed]
这些文件是用UTF-8编码的,包括许多不同的语言,所有的数据都要保留下来,所以不能选择向下编码为ASCII。但是,SQL Server不支持UTF-8的大容量插入

我将此作为一个C#命令行应用程序编写,并使用以下方法对每个文件进行预处理,该方法去除注释行以及文件末尾的最后换行符,并将文件从UTF-8转换为UTF-16:

    public void PrepareAppleEPFFile(string dataFilePath, string cleanedFilePath)
{
    if (File.Exists(cleanedFilePath))
        { return; } // Skip processing if file already exists

    using (StreamReader reader = new StreamReader(dataFilePath, Encoding.UTF8))
    {
        using (StreamWriter writer = new StreamWriter(cleanedFilePath, false, Encoding.Unicode))
        {
            string line;
            bool firstLine = true;
            while (!reader.EndOfStream)
            {
                line = reader.ReadLine();
                if (line.Length > 0 && line.Substring(0, 1) != "#") // Skip empty and commented lines
                {
                    // Done this way to avoid adding a trailing newline, which breaks BULK INSERT
                    if (!firstLine)
                    {
                        writer.Write("\n");     
                    }
                    writer.Write(line);
                    firstLine = false;
                }
            }
        }
    }
}
准备好文件后,我将使用以下批量插入语句:

BULK INSERT dbo.Application
FROM 'C:\iTunes\data\application.cleaned'
WITH ( 
    TABLOCK,
    DATAFILETYPE =  'widechar',
    ERRORFILE = 'C:\iTunes\Logs\application.log',
    FORMATFILE = 'C:\iTunes\FormatDefinitions\Application.xml'
    )
它使用以下XML格式文件:

<?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="\x01\x00"/>
  <FIELD ID="2" xsi:type="CharTerm"  TERMINATOR="\x01\x00"/>
  <FIELD ID="3" xsi:type="CharTerm"  TERMINATOR="\x01\x00"/>
  <FIELD ID="4" xsi:type="CharTerm"  TERMINATOR="\x01\x00"/>
  <FIELD ID="5" xsi:type="CharTerm"  TERMINATOR="\x01\x00"/>
  <FIELD ID="6" xsi:type="CharTerm"  TERMINATOR="\x01\x00"/>
  <FIELD ID="7" xsi:type="CharTerm"  TERMINATOR="\x01\x00"/>
  <FIELD ID="8" xsi:type="CharTerm"  TERMINATOR="\x01\x00"/>
  <FIELD ID="9" xsi:type="CharTerm"  TERMINATOR="\x01\x00"/>
  <FIELD ID="10" xsi:type="CharTerm" TERMINATOR="\x01\x00"/>
  <FIELD ID="11" xsi:type="CharTerm" TERMINATOR="\x01\x00"/>
  <FIELD ID="12" xsi:type="CharTerm" TERMINATOR="\x01\x00"/>
  <FIELD ID="13" xsi:type="CharTerm" TERMINATOR="\x01\x00"/>
  <FIELD ID="14" xsi:type="CharTerm" TERMINATOR="\x01\x00"/>
  <FIELD ID="15" xsi:type="CharTerm" TERMINATOR="\x01\x00"/>
  <FIELD ID="16" xsi:type="CharTerm" TERMINATOR="\x01\x00"/>
  <FIELD ID="17" xsi:type="CharTerm" TERMINATOR="\x02"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="2" NAME="application_id" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="3" NAME="title" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="4" NAME="recommended_age" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="5" NAME="artist_name" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="6" NAME="seller_name" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="7" NAME="company_url" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="8" NAME="support_url" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="9" NAME="view_url" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="10" NAME="artwork_url_large" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="11" NAME="artwork_url_small" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="12" NAME="itunes_release_date" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="13" NAME="copyright" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="14" NAME="description" xsi:type="SQLNTEXT"/>
  <COLUMN SOURCE="15" NAME="version" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="16" NAME="itunes_version" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="17" NAME="download_size" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="1" NAME="export_date" xsi:type="SQLNVARCHAR"/>
 </ROW>
</BCPFORMAT>
对于标题为7个字符的行,上面的查询返回值28表示标题的DATALENGTH_,返回值14表示标题的DATALENGTH_。这些值是其应有值的两倍。大容量插入似乎试图对已经存在的unicode数据进行重新编码,从而生成双编码数据,其中每个字符后面都有3个字符(0),而不是一个字符

另一个不太严重的问题是,在UTF-16中写入数据文件会导致将BOM添加到文件的开头,而BOM序列最终会作为文件第一行中第一个字段值的一部分插入

我尝试过为bulkinsert命令的CODEPAGE参数使用不同的值,但是没有一个值能够改善这种情况,而那些确实起作用的值导致了bulkinsert失败。例如,使用CODEPAGE=1200(UTF-16的代码页)会导致以下错误:

Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the 
specified codepage) for row 1, column 1 (export_date).

在查看XML格式文件的文档时,我终于找到了问题所在:

问题是我在元素中使用了xsi:type=“CharTerm”,而我本应该使用xsi:type=“NCharTerm”

Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the 
specified codepage) for row 1, column 1 (export_date).