【问题标题】:Using SSIS to transfer a CSV file that contains SQL (i.e., potential special characters) in it使用 SSIS 传输包含 SQL(即潜在特殊字符)的 CSV 文件
【发布时间】:2013-06-22 06:41:53
【问题描述】:

使用 SSIS 传输包含 SQL 的 CSV 文件。

我正在使用 .NET 创建一个 CSV 文件,然后我使用 SSIS 包将其传输到表中。

文件的内容是一个 36 字符的 GUID 和任何可能包含制表符、管道字符和可能任何可键入字符的 SQL 文本。我想我会使用 Windows CharMap 附件实用程序指定我自己的列和行分隔符,以选择不可键入的字符作为分隔符。我分别选择了 ¼ 和 ½ 作为列和行分隔符。

我创建的测试文件如下所示:

Guid¼Sql½3afc912b-917d-4719-8ded-22e5d95930a3¼SELECT 
 * FROM 
 TABLE½a867fa30-f2c7-459e-8985-9ef42616991e¼SELECT 
 * FROM 
 TABLE½

文件 SSIS 文件连接将列定义为

 Guid: string [DT_STR] 36 
 Sql: text stream [DT_TEXT]

我正在将其传输到以下 SQL Server 目标表:

CREATE TABLE [dbo].[CodeObjectSql](
    [Guid] [char](36) NOT NULL,
    [Sql] [varchar](max) NOT NULL
) ON [PRIMARY]

当我预览文件时,列分隔符显示为 guid 第一列的最后一个(第 37 个)字符,而行分隔符显示为 SQL 列值的最后一个字符。

这是我得到的错误:

Error: 0xC02020A1 at Load CodeObjectSql, CodeObjectSql File [1]: Data conversion failed. The data conversion for column "Guid" returned status value 4 and status text "Text was truncated or one or more characters had no match in the target code page.".
Error: 0xC020902A at Load CodeObjectSql, CodeObjectSql File [1]: The "output column "Guid" (10)" failed because truncation occurred, and the truncation row disposition on "output column "Guid" (10)" specifies failure on truncation. A truncation error occurred on the specified object of the specified component.
Error: 0xC0202092 at Load CodeObjectSql, CodeObjectSql File [1]: An error occurred while processing file "C:\CodeObjectSql.csv" on data row 2.
Error: 0xC0047038 at Load CodeObjectSql, SSIS.Pipeline: SSIS Error Code DTS_E_PRIMEOUTPUTFAILED.  The PrimeOutput method on component "CodeObjectSql File" (1) returned error code 0xC0202092.  The component returned a failure code when the pipeline engine called PrimeOutput(). The meaning of the failure code is defined by the component, but the error is fatal and the pipeline stopped executing.  There may be error messages posted before this with more information about the failure.

然后我尝试将文件更改为 Unicode,并将列类型修改为它们的 unicode 等效项

 Guid: string [DT_WSTR] 36 
 Sql: text stream [DT_NTEXT]

仍然没有运气。

我的经验是,SSIS 无法处理数据中出现的行或列分隔符,方法是使用文本限定符字符并在文本值中加倍特殊字符来表示数据中的一次出现。

如果根据我的测试,我的假设都是正确的,那么用于这种类型数据的最佳格式是什么?

尝试创建此表并将数据粘贴到输入文件中,然后亲自查看。 :-)

【问题讨论】:

    标签: sql-server-2008 ssis


    【解决方案1】:

    测试文件:全部在一行。

    Guid¼Sql½3afc912b-917d-4719-8ded-22e5d95930a3¼SELECT * FROM TABLE½a867fa30-f2c7-459e-8985-9ef42616991e¼SELECT * FROM TABLE½
    

    平面文件源编辑器配置:

    Code Page: 1252
    Format: Delimited
    Text Qualifier: <none>
    Header row delimiter:{CR/LF}
    Header Rows to skip: 0
    Column names in the first data row: Checked
    

    现在转到列:

    Row delimiter: 1/2
    Column Delimiter: 1/4
    

    问题/建议:你不能简化你的分隔符吗?使用 1/2 和 1/4 是不寻常的。

    另外:右键单击数据源。转到输入和输出属性选项卡 // 输出列 // Guid。将字段属性更改为 DT-STR (36)。

    【讨论】:

    • 您将数据全部放在一行上,但我正在寻找有关如何导入 CSV 文件的答案,即数据是数据库中的脚本存储过程。脚本中可以包含 CR\LF 字符、制表符、竖线字符和逗号。我选择奇怪的派系角色作为我的行和列分隔符的原因是它们不寻常并且不太可能出现在数据中!另外,我以前是我们的 DT-STR(36),但我得到了上面显示的错误。那时我拼命尝试了 unicode 等价于无济于事。
    • ChadD -- 一些 cmets: 1. 抱歉,我没有正确理解您的输入文件格式,因此使用了全单行格式。我将处理确切的格式并回复 2。如果您正在创建源文件(而不是其他人发送它),您将拥有更多的灵活性。您不能利用这种灵活性来创建更一致的输出吗? Guid1/2Sqlxxx1/2SQL1xxx21/2SQL2?
    • ChadD - 我试过但做不到。我强烈认为需要修改生成此源文件的过程,以便输出是格式良好的 CSV(字符分隔值)。您可以发布生成源文件的代码吗?我有兴趣查看和学习您的解决方案。问候!
    • 它一直困扰着我! (以一种好的方式)。考虑读取所有行并将它们放在一个文件中。然后我原来的解决方案就可以了。如果您想使用它,这里给出了部分代码:using (StreamReader reader = new StreamReader("input.txt")) { string line; while ((line = reader.ReadLine()) != null) { Console.Write(line); } }
    【解决方案2】:

    脚本任务代码:

    public void Main()
        {
            FileStream fs1 = new FileStream(@"C:\Temp\half.txt", FileMode.Open, FileAccess.Read);
            FileStream fs2 = new FileStream(@"c:\Temp\AllOnOne.txt", FileMode.Create);
    
            BinaryReader r = new BinaryReader(fs1);
            BinaryWriter w = new BinaryWriter(fs2);
    
            // Read data 
            for (int i = 0; i < fs1.Length; i++)
            {
                byte b = r.ReadByte();
    
                if (!b.Equals(Convert.ToByte('\n')) && !b.Equals(Convert.ToByte('\r')))
                {
                    w.Write(b);
                }
            }
    
            w.Close();
            r.Close();
    
            fs2.Close();
            fs1.Close();           
    
            Dts.TaskResult = (int)ScriptResults.Success;
        }
    

    DFT -- 使用我之前回答中描述的设置。

    half.txt 的内容正是您在问题中提到的内容。请让我们知道它对您有用。如果您找到其他解决方案,请发布。

    【讨论】:

      猜你喜欢
      • 2016-03-09
      • 1970-01-01
      • 1970-01-01
      • 2013-03-11
      • 2016-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多