2013-12-10 26 views
1

我写了一个C#控制台程序,读取制表符分隔的文件并执行C#BCP到SQL Server

bcp tblName + " in " + outputfilename + " -c -T -S servername\instancename 
     -U readonly -P readonly -F2"; 

第一列是EmpID这是一个int和第二列EMPName这是Varchar2(100)EMPLOYER VARCHAR(200)

outputfilename有时会出现错误,而数据输入人员忘记在第1列中输入empID,或者有时输入员工姓名时,他们会转到下一行。

EMPID EMPNAME  EMPLOYER 
100  Ann Taylor A Corporation 
Brian Tao B Corporation 
200  Cindy 
Smith C Corporation 
400  Daryl John "D Corporation 

第一行是正确的。

第二行,因为没有EMPID,我想获取行号并将其记录为错误。

列#3,虽然史密斯是辛迪的姓氏没有办法知道,因此只有200辛迪获取保存的方式,但由于史密斯不是由数

列#4之前日志应报告错误,缺少双引号,报告日志文件中的错误。

可以这样做吗?

感谢 MR

回答

1

您可以尝试在你的C#应用​​程序预处理输入文件。逐行读取它,尝试解析,检测所有错误,报告它们并将结果输出到另一个文件,然后传递给bcp

+0

你怎么能解析?我如何编写这些规则?这是我的问题 – user2726975

+0

那么,使用分隔符分割字符串,看看你是否可以在第一列解析ID。如果是,请检查第二个和第三个字符串 - 一切正常 - 将其写入输出。如果第三个字符串丢失,请检查下一行等... – sha

1

AFAIK,有没有简单的方法与BCP做到这一点。 BCP通常对输入文件的列/行格式不正常不容许。

既然你已经在C#了,我的建议是考虑使用SQLBulkCopy API来代替。它几乎与BCP一样快,并将所有输入文件处理到您的程序。它最初比BCP多一点,但是一旦你有了一个工作实例,为程序员提供了更多的灵活性和选择。

此MSDN线程有一个示例sanka060707如何使用它从c#http://social.msdn.microsoft.com/Forums/en-US/4929a0a8-0137-45f6-86e8-d11e220048c3/creating-a-new-table-in-sql-server-from-adonet-datatable?forum=adodotnetdataproviders(这是关于第五个问题的答复)。这是它的副本(长)

public class SqlTableCreator 
{ 
    #region Instance Variables 
    private SqlConnection _connection; 
    public SqlConnection Connection { 
     get { return _connection; } 
     set { _connection = value; } 
    } 

    private SqlTransaction _transaction; 
    public SqlTransaction Transaction { 
     get { return _transaction; } 
     set { _transaction = value; } 
    } 

    private string _tableName; 
    public string DestinationTableName { 
     get { return _tableName; } 
     set { _tableName = value; } 
    } 
    #endregion 

    #region Constructor 
    public SqlTableCreator() { } 
    public SqlTableCreator(SqlConnection connection) : this(connection, null) { } 
    public SqlTableCreator(SqlConnection connection, SqlTransaction transaction) { 
     _connection = connection; 
     _transaction = transaction; 
    } 
    #endregion 

    #region Instance Methods 
    public object Create(DataTable schema) { 
     return Create(schema, null); 
    } 
    public object Create(DataTable schema, int numKeys) { 
     int[] primaryKeys = new int[numKeys]; 
     for (int i = 0; i < numKeys; i++) { 
      primaryKeysIdea = i; 
     } 
     return Create(schema, primaryKeys); 
    } 
    public object Create(DataTable schema, int[] primaryKeys) { 
     string sql = GetCreateSQL(_tableName, schema, primaryKeys); 

     SqlCommand cmd; 
     if (_transaction != null && _transaction.Connection != null) 
      cmd = new SqlCommand(sql, _connection, _transaction); 
     else 
      cmd = new SqlCommand(sql, _connection); 

     return cmd.ExecuteNonQuery(); 
    } 

    public object CreateFromDataTable(DataTable table) { 
     string sql = GetCreateFromDataTableSQL(_tableName, table); 

     SqlCommand cmd; 
     if (_transaction != null && _transaction.Connection != null) 
      cmd = new SqlCommand(sql, _connection, _transaction); 
     else 
      cmd = new SqlCommand(sql, _connection); 

     return cmd.ExecuteNonQuery(); 
    } 
    #endregion 

    #region Static Methods 

    public static string GetCreateSQL(string tableName, DataTable schema, int[] primaryKeys) { 
     string sql = "CREATE TABLE " + tableName + " (\n"; 

     // columns 
     foreach (DataRow column in schema.Rows) { 
      if (!(schema.Columns.Contains("IsHidden") && (bool)column["IsHidden"])) 
       sql += column["ColumnName"].ToString() + " " + SQLGetType(column) + ",\n"; 
     } 
     sql = sql.TrimEnd(new char[] { ',', '\n' }) + "\n"; 

     // primary keys 
     string pk = "CONSTRAINT PK_" + tableName + " PRIMARY KEY CLUSTERED ("; 
     bool hasKeys = (primaryKeys != null && primaryKeys.Length > 0); 
     if (hasKeys) { 
      // user defined keys 
      foreach (int key in primaryKeys) { 
       pk += schema.Rows[key]["ColumnName"].ToString() + ", "; 
      } 
     } 
     else { 
      // check schema for keys 
      string keys = string.Join(", ", GetPrimaryKeys(schema)); 
      pk += keys; 
      hasKeys = keys.Length > 0; 
     } 
     pk = pk.TrimEnd(new char[] { ',', ' ', '\n' }) + ")\n"; 
     if (hasKeys) sql += pk; 
     sql += ")"; 

     return sql; 
    } 

    public static string GetCreateFromDataTableSQL(string tableName, DataTable table) { 
     string sql = "CREATE TABLE [" + tableName + "] (\n"; 
     // columns 
     foreach (DataColumn column in table.Columns) { 
      sql += "[" + column.ColumnName + "] " + SQLGetType(column) + ",\n"; 
     } 
     sql = sql.TrimEnd(new char[] { ',', '\n' }) + "\n"; 
     // primary keys 
     if (table.PrimaryKey.Length > 0) { 
      sql += "CONSTRAINT [PK_" + tableName + "] PRIMARY KEY CLUSTERED ("; 
      foreach (DataColumn column in table.PrimaryKey) { 
       sql += "[" + column.ColumnName + "],"; 
      } 
      sql = sql.TrimEnd(new char[] { ',' }) + "))\n"; 
     } 

     return sql; 
    } 

    public static string[] GetPrimaryKeys(DataTable schema) { 
     List<string> keys = new List<string>(); 

     foreach (DataRow column in schema.Rows) { 
      if (schema.Columns.Contains("IsKey") && (bool)column["IsKey"]) 
       keys.Add(column["ColumnName"].ToString()); 
     } 

     return keys.ToArray(); 
    } 

    // Return T-SQL data type definition, based on schema definition for a column 
    public static string SQLGetType(object type, int columnSize, int numericPrecision, int numericScale) { 
     switch (type.ToString()) { 
      case "System.String": 
       return "VARCHAR(" + ((columnSize == -1) ? 255 : columnSize) + ")"; 

      case "System.Decimal": 
       if (numericScale > 0) 
        return "REAL"; 
       else if (numericPrecision > 10) 
        return "BIGINT"; 
       else 
        return "INT"; 

      case "System.Double": 
      case "System.Single": 
       return "REAL"; 

      case "System.Int64": 
       return "BIGINT"; 

      case "System.Int16": 
      case "System.Int32": 
       return "INT"; 

      case "System.DateTime": 
       return "DATETIME"; 

      default: 
       throw new Exception(type.ToString() + " not implemented."); 
     } 
    } 

    // Overload based on row from schema table 
    public static string SQLGetType(DataRow schemaRow) { 
     return SQLGetType(schemaRow["DataType"], 
          int.Parse(schemaRow["ColumnSize"].ToString()), 
          int.Parse(schemaRow["NumericPrecision"].ToString()), 
          int.Parse(schemaRow["NumericScale"].ToString())); 
    } 
    // Overload based on DataColumn from DataTable type 
    public static string SQLGetType(DataColumn column) { 
     return SQLGetType(column.DataType, column.MaxLength, 10, 2); 
    } 
    #endregion 
} 
+0

哇!这是非常有用的..我会试试这个。非常感谢 – user2726975