0

我有一个应用程序(当前)需要使用 SQL Server 2000 和 SQL Server 2005 提供的数据库。

我正在尝试以编程方式将数据库从一台服务器移动到另一台服务器。我使用的所有表都有一个自动递增的主键。由于这些自动增量键在其他表中用作外键,因此我复制表的攻击计划是暂时关闭目标表上的自动增量,逐字插入记录(使用原始主键),然后打开自动- 重新增加。

如果我理解正确,我可以通过执行一次“打开/关闭自动增量”一个表

SET IDENTITY_INSERT tbl_Test ON;
...
SET IDENTITY_INSERT tbl_Test OFF;

我的实现是在 VB 2005 中,使用 System.Data.SqlClient。

为简洁起见,我将只显示与 SQL 查询的构造相关的代码行。

要创建表:

    Dim createTableStatement As String = _
        "CREATE TABLE tbl_Test (" & _
            "ID_Test INTEGER PRIMARY KEY IDENTITY," & _
            "TestData INTEGER" & _
            ")"
    Dim createTableCommand As New SqlCommand(createTableStatement, connection)

    createTableCommand.ExecuteNonQuery()

要打开或关闭 IDENTITY_INSERT:

    Dim turnOffIdentInsertStatement As String = _
        "SET IDENTITY_INSERT tbl_Test OFF;"
    Dim turnOffIdentInsertCommand As New SqlCommand(turnOffIdentInsert, connection)
    turnOffIdentInsertCommand.ExecuteNonQuery()

    Dim turnOnIdentInsertStatement As String = _
        "SET IDENTITY_INSERT tbl_Test ON;"
    Dim turnOnIdentInsertCommand As New SqlCommand(turnOnIdentInsert, connection)
    turnOnIdentInsertCommand.ExecuteNonQuery()

正常插入新记录,不指定主键:

    Dim insertRegularStatement As String = _
        "INSERT INTO tbl_Test (TestData) VALUES (42);"
    Dim insertRegularCommand As New SqlCommand(insertRegularStatement, connection)
    insertRegularCommand.ExecuteNonQuery()

要插入具有显式主键的新记录:

    Dim insertWithIDStatement As String = _
        "INSERT INTO tbl_Test (ID_Test, TestData) VALUES (20, 42);"
    Dim insertWithIDCommand As New SqlCommand(insertWithIDStatement, connection)
    insertWithIDCommand.ExecuteNonQuery()

所以,我的计划是调用打开 IDENTITY_INSERT 的代码,添加带有显式主键的记录,然后关闭 IDENTITY_INSERT。

当我与 SQL Server 2000 交谈时,此方法似乎可以正常工作,但是当我尝试针对 SQL Server 2005 使用完全相同的代码时遇到了异常:

"Cannot insert explicit value for identity column in table 'tbl_Test' when IDENTITY_INSERT is set to OFF."

有什么提示吗?一如既往地提前感谢。

4

3 回答 3

2

SqlBulkCopy值得一看,因为它在导入批量数据时进行了优化。

根据场景,还值得研究的是使用 SSIS 任务批量复制数据(也使用批量复制 API)或使用BULK INSERT语句(同样,批量复制 API)链接服务器。

至于设置标识是在set identity_insert与插入相同的连接上执行的语句吗?由于 SQL Server 2005 仅在当前连接上保留该设置。

在 SQL Server 2008 Express 上,以下对我来说效果很好:

using (var conn = CreateConnection())
{
    conn.Open();
    new SqlCommand("SET IDENTITY_INSERT Foo ON", conn).ExecuteNonQuery();
    new SqlCommand("INSERT INTO Foo(id) VALUES (1)", conn).ExecuteNonQuery();
    new SqlCommand("SET IDENTITY_INSERT Foo OFF", conn).ExecuteNonQuery();
}
于 2009-09-08T21:36:20.723 回答
1

您可能必须在语句之后插入 GOSET IDENTITY ... ON语句。

于 2009-09-08T21:16:38.713 回答
1

在 SQL 查询分析器会话中,我会在 IDENTITY_INSERT 之后和实际插入之前发出 GO。也许这也适用于从代码中调用它?

于 2009-09-08T21:17:09.770 回答