挣扎于SQL BCP(uniqidentifier,列的默认值……)

|| 编辑:我唯一未解决的问题是c)(文件上为True和False,数据库上为位,我既不能更改文件也不能更改数据库方案,无法触摸的太字节为数百TB)。 系统接收具有特定格式的文件(实际上是数十万个文件)。事情是: a)第一种是uniqidentifier(稍后会详细介绍) b)在数据库上,表的前4个值是由数据库生成的(它们与日期有关),这意味着在文件中找不到这4个值(所有其余值都是-并且按顺序排列-即使它总是以文本表示或为空) c)在文件上用假/真表示位值。 因此,1的问题是在我收到的输入文本文件中,uniqidentifier使用括号。当我尝试使用bcp命令工具生成具有格式nul选项的文件时,它将使它成为具有37个字符的sqlchar(这对我来说没有意义,因为它可能是36或38)。 行分隔符为\“ +++ \\ r \\ n \”,列分隔符为\“©®©\”。 我将如何生成格式文件?我已经坚持了一段时间,我以前从未使用过bcp,而且我得到的错误并不能说明太多(\“ BCP数据文件中遇到意外的EOF \”) 我应该指定格式文件中的所有列还是仅指定我希望从获取的文件中读取的列? 谢谢! 注意:我无法提供SQL模式,因为它是针对我所在的公司的。但这几乎是:smalldate,tinyint,tinyint,tinyint(这四个是由数据库生成的),uniqidentifier,char,char,更多的varchar,一些位,更多的varchars,一些nvarchar。除数据库生成的值外,所有值均接受null。 我当前的问题是跳过前4列。 http://msdn.microsoft.com/zh-CN/library/ms179250(v=SQL.105).aspx 我遵循了该指南,但是不知何故。这是所做的更改(我只是在硬更改列名以保护项目的私密性,即使听起来很愚蠢) 这是使用bcp生成的格式(格式为nul -c)-请注意,我将其作为链接\因为它不是那么短- http://pastebin.com/4UkpPp1n 第二个应该做相同的事情,但是忽略了前4列,在下一个pastebin中: http://pastebin.com/Lqj6XSbW 但是它没有用。错误是\“ Error = [Microsoft] [SQL Native Client]为bcp操作提供的字段数小于服务器上的列数。\”,这应该是所有目的。 任何帮助将不胜感激。     
已邀请:
我将为GUID创建一个新表,并以“ 0”开头。将数据导入到该临时表中,然后使用with1进行转换,以将临时数据导入到永久表中。这种方法也适用于奇数格式的日期,带货币符号的数字或一般任何格式较差的输入。 BCP格式文件有些麻烦,但从根本上讲并不太复杂。如果那部分继续给您带来麻烦,一种选择是将整个行作为单个
VARCHAR(1000)
字段导入,然后在SQL中拆分它-如果您对SQL文本处理感到满意。 另外,如果您熟悉其他一些编程语言(例如Perl或C#),则可以创建脚本以将输入内容预处理为更友好的形式(如制表符分隔)。如果您不熟悉其他编程语言,建议您选择一种并开始使用! SQL是一种很棒的语言,但是有时候您需要一个不同的工具。这对文本处理不是很好。 如果您熟悉C#,这是我生成代码文件的代码。没有人会取笑我的白石压痕:P
private static string  CreateFormatFile(string filePath, SqlConnection connection, string tableName, string[] sourceFields, string[] destFields, string fieldDelimiter, string fieldQuote)
    {
    string         formatFilePath = filePath + \".fmt\";
    StreamWriter   formatFile     = null;
    SqlDataReader  data           = null;
    try
        {
        // Load the metadata for the destination table, so we can look up fields\' ordinal positions
        SqlCommand  command = new SqlCommand(\"SELECT TOP 0 * FROM \" + tableName, connection);
                    data    = command.ExecuteReader(CommandBehavior.SchemaOnly);
        DataTable   schema  = data.GetSchemaTable();

        Dictionary<string, Tuple<int, int>>  metadataByField = new Dictionary<string, Tuple<int, int>>();
        foreach (DataRow row in schema.Rows)
            {
            string  fieldName = (string)row[\"ColumnName\"];
            int     ordinal   = (int)row[\"ColumnOrdinal\"] + 1;
            int     maxLength = (int)row[\"ColumnSize\"];
            metadataByField.Add(fieldName, new Tuple<int, int>(ordinal, maxLength));
            }

        // Begin the file, including its header rows
        formatFile = File.CreateText(formatFilePath);
        formatFile.WriteLine(\"10.0\");
        formatFile.WriteLine(sourceFields.Length);

        // Certain strings need to be escaped to use them in a format file
        string  fieldQuoteEscaped     = fieldQuote     == \"\\\"\" ? \"\\\\\\\"\" : fieldQuote;
        string  fieldDelimiterEscaped = fieldDelimiter == \"\\t\" ? \"\\\\t\"  : fieldDelimiter;

        // Write a row for each source field, defining its metadata and destination field
        for (int i = 1;  i <= sourceFields.Length;  i++)
            {
            // Each line contains (separated by tabs): the line number, the source type, the prefix length, the field length, the delimiter, the destination field number, the destination field name, and the collation set
            string  prefixLen   = i != 1 || fieldQuote == null ? \"0\" : fieldQuote.Length.ToString();
            string  fieldLen;
            string  delimiter   = i < sourceFields.Length ? fieldQuoteEscaped + fieldDelimiterEscaped + fieldQuoteEscaped : fieldQuoteEscaped + @\"\\r\\n\";
            string  destOrdinal;
            string  destField   = destFields[i - 1];
            string  collation;
            if (destField == null)
                {
                // If a field is not being imported, use ordinal position zero and a placeholder name
                destOrdinal = \"0\";
                fieldLen    = \"32000\";
                destField   = \"DUMMY\";
                collation   = \"\\\"\\\"\";
                }
            else
                {
                Tuple<int, int>  metadata;
                if (metadataByField.TryGetValue(destField, out metadata) == false)  throw new ApplicationException(\"Could not find field \\\"\" + destField + \"\\\" in table \\\"\" + tableName + \"\\\".\");
                destOrdinal = metadata.Item1.ToString();
                fieldLen    = metadata.Item2.ToString();
                collation   = \"SQL_Latin1_General_CP1_CI_AS\";
                }
            string  line = String.Join(\"\\t\", i, \"SQLCHAR\", prefixLen, fieldLen, \'\"\' + delimiter + \'\"\', destOrdinal, destField, collation);
            formatFile.WriteLine(line);
            }

        return formatFilePath;
        }
    finally
        {
        if (data       != null)  data.Close();
        if (formatFile != null)  formatFile.Close();
        }
    }
出于某些原因,我当时没有使用ѭ4use块作为数据读取器。     
似乎BCP不可能将True和False理解为位值。最好使用SSIS或先替换文本内容(创建视图或类似方法不是一个好主意,这会增加开销)。     

要回复问题请先登录注册