为什么我的SqlBulkCopy不起作用

时间:2012-02-08 07:32:53

标签: c# asp.net sql-server-2005 sqlbulkcopy

我正在使用SqlBulkCopy对象将数据表写入sql server表。但是,每次我重新检查我的数据库时,它都保持原样,没有任何变化。甲

我尝试过谷歌搜索以确定我的问题,但我无法解决。

数据表来自.xls文件。

public static DataTable dt = new DataTable();

private void ExportToGrid(String path, String filen)
    {
        int idx = filen.IndexOf(".");
        string tf = filen.Remove(idx, 4);

        OleDbConnection MyConnection = null;
        DataSet DtSet = null;
        OleDbDataAdapter MyCommand = null;
        MyConnection = new OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0; Data Source='" + path + "';Extended Properties=Excel 8.0;");

        ArrayList TblName = new ArrayList();

        MyConnection.Open();
        DataTable schemaTable = MyConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
        foreach (DataRow row in schemaTable.Rows)
        {
            TblName.Add(row["TABLE_NAME"]);
        }

        MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + TblName[0].ToString() + "]", MyConnection);
        DtSet = new System.Data.DataSet();

        MyCommand.Fill(DtSet);
        MyCommand.FillSchema(DtSet, SchemaType.Source);

        DataTable dt = new DataTable();
        dt = DtSet.Tables[0];
        Session["dt"] = dt;
        int x = dt.Rows.Count;
        MyConnection.Close();

        if (dt.Rows.Count > 0)
        {
            theGridView.DataSource = dt;
            theGridView.DataBind();
        }

        if (System.IO.File.Exists(path))
        {
            System.IO.File.Delete(path);
        }

    }

这是我的作家功能

private void StartImport()
    {
        string servername = server;
        string database = database;
        string tbl = "dbo.LinkDb";

        Stopwatch sw = new Stopwatch();
        sw.Start();
        SqlBulkCopy bulkCopy = new SqlBulkCopy("Data Source=" + servername + ";Initial Catalog=" + database + ";Integrated Security=SSPI", SqlBulkCopyOptions.TableLock);
        bulkCopy.DestinationTableName = tbl;
        bulkCopy.WriteToServer(dt);
        sw.Stop();
        lblResult.Visible = true;
        lblResult.Text = (sw.ElapsedMilliseconds / 1000.00).ToString();
    }

以下是我的sql server中存储的表的屏幕截图。我向你保证,我一直遵守判例敏感规则。

Tables

没有抛出异常,平均时间为0.018 - 0.020秒

感谢任何帮助。

谢谢

2 个答案:

答案 0 :(得分:2)

根据您发布的代码,您正在向数据库写入一个空的数据表。你的“ExportToGrid”方法填充dt,一个在本地声明的DataTable,它丢失了方法之外的范围。您的写函数正在调用静态DataTable dt,这是一个新的数据表。

dt是否需要是静态的?似乎这可以声明为

private DataTable dt;

然后在“ExportToGrid”内部而不是声明另一个DataTable只是实例化已经声明的dt而不是声明一个新的

dt = new DataTable();

或者,您可以在写入方法期间直接从GridView中提取DataTable:

DataTable dt = (DataTable)theGridView.DataSource;
bulkCopy.WriteToServer(dt);

这消除了对方法范围之外的变量的需要。

最后,由于您在会话中存储数据表(我通常不主张在会话变量中存储大量数据但不知道您网站的具体情况我无法通过判断),您可以使用以下内容:

DataTable dt = (DataTable)Session["dt"];
bulkCopy.WriteToServer(dt);

答案 1 :(得分:0)

除了我将数据表中的列显式映射到数据库表之外,我没有看到与我的使用相比显而易见的事情。

Using cn As New SqlConnection(DataAccessResource.CONNECTIONSTRING)
    cn.Open()
    Using copy As New SqlBulkCopy(cn)
        copy.BulkCopyTimeout = 300
        copy.ColumnMappings.Add(0, 0)
        copy.ColumnMappings.Add(1, 1)
        copy.ColumnMappings.Add(2, 2)
        copy.ColumnMappings.Add(3, 3)
        copy.DestinationTableName = "Tablename"
        copy.WriteToServer(dataset.datatable)
    End Using
End Using

连接字符串(sql server 2000!)看起来像

"data source=DBSERVERNAME;initial catalog=DBNAME;persist security info=True;user id=USERNAME;password=PASSWORD;packet size=4096"

我怀疑连接字符串是一个问题,假设你在其他地方使用它。

最后,您检查了数据集数据表中的列的数据类型是否与数据库中的列匹配。根据我的经验,来自excel的oledb加载并不总是产生您可能期望的输出,日期字段和具有混合文本和数字的列是特定问题。