没有列名列表的tsql标识插入

时间:2010-07-27 15:04:36

标签: sql-server tsql

我要将一些数据从一个数据库转储到另一个数据库。我正在使用

set identity_insert MyTable on
GO
INSERT INTO MyTable SELECT * FROM sourceDB.dbo.MyTable
GO
set identity_insert MyTable off

无论如何要让它发挥作用?有30个表,将列名列表添加到insert语句将非常耗时。我正在使用SQL Server 2000.将在不久的将来升级到SQL Server 2008。

编辑: MyTable有一个标识列。

4 个答案:

答案 0 :(得分:5)

只需从对象浏览器中拖放列名即可。你可以一步完成,比编写select *需要大约1秒钟。你不应该在生产代码中使用select *。这是一种糟糕的做法。

我担心你插入Identity列,这几乎是不可能的。如果原始表的某些标识列与新表中的退出ID相同,该怎么办?在决定从另一个表中插入id值之前,请务必检查这一点。我更喜欢对父表进行插入并获取一个新的id并将其与旧的id匹配(2008年输出很好),然后对任何子表使用新的id,但是加入旧的id。

答案 1 :(得分:3)

刚刚在SQL Server 2000 SP2计算机上尝试过这种情况,我收到此错误,似乎证实了您的观察结果。

  

只有在使用列列表且IDENTITY_INSERT为ON时,才能指定表'Foo2'中标识列的显式值。

set identity_insert Foo2 on
GO
INSERT INTO Foo2 select top 100 * from Foo where id > 110000
GO
set identity_insert Foo2 off

SELECT INTO建议只会有助于将数据导入临时表。在某些时候,您必须明确说明列名称。

提示列名:突出显示SSMS查询中的表格,然后按Alt-F1(sp_help的快捷方式)。然后,您可以将生成的column_name复制/粘贴到查询中,只需手动添加逗号即可。快捷方式,将它们粘贴到Excel中,键入一个逗号,然后复制列。

答案 2 :(得分:1)

HLGEM的答案对于许多表都不切实际。我处于一种情况,我们不时运行一个脚本来清除开发和测试数据库,这使开发人员之一大喊大叫。显然,现在有22个表不应包含在该清除过程中。好东西,我有一个备份。我将表名放在一个名为“ undo”的临时表中,并使用以下内容生成列列表:

private void TextBox1_Initialized(object sender, RoutedEventArgs e)
{
    BackgroundWorker bw = new BackgroundWorker();
    bw.WorkerReportsProgress = true;
    bw.DoWork += new DoWorkEventHandler(delegate (object o, DoWorkEventArgs args)
    {

    });
    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object o, RunWorkerCompletedEventArgs args)
    {
        TextBox1.Text = Registry.GetValue(@"HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0", "ProcessorNameString", null).ToString().Replace("(R)", "").Replace("(TM)", "") + Environment.NewLine;
        TextBox1.Text += "Memory:  " + getRAMsize() + Environment.NewLine;
        TextBox1.Text += "Free Space:  " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
        if (Is64BitSystem)
        {
            TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
        }
        else
        {
            TextBox1.Text += getOS() + " 32bit" + Environment.NewLine;
        }
        TextBox1.Text += diskname() + Environment.NewLine;
        TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$&-").TrimEnd('-') + Environment.NewLine;
        TextBox1.Text += av();
    });
    bw.RunWorkerAsync();
}

然后我将输出复制到Excel,并使用ye olde = CONCATENATE函数生成所有IDENTITY_INSERT和INSERT INTO语句,然后复制/粘贴回SSMS,瞧!是的,Excel是您的朋友。

答案 3 :(得分:0)

如果您不需要保留ID列的值,您可以:

删除ID列

在新目标数据库的新架构中创建一个ID列(使其成为列列表中的最后一列)

INSERT INTO newdb.dbo.newtable
SELECT * FROM olddb.dbo.oldtable

它会在生成新ID信息时保留其余列。