在SQL中克隆行的最快方法

时间:2009-09-25 23:32:44

标签: sql sql-server sql-server-2005 tsql

我想要克隆具有单个主键(PrimKey)的多个表的行。在SQL Server 2005中克隆行的最快方法是什么?

这是一个例子,

克隆PrimKey1以获取PrimKey2。所以我尝试以下方法:

INSERT INTO PrimKeys 
SELECT 'PrimKey2' AS PrimKey,* 
  FROM PrimKeys 
 WHERE PrimKey='PrimKey1'

但当然这里的问题是,PrimKey列在内部SELECT语句中重复出现。有没有其他类似的简单方法与上述相似?


谢谢大家的回复。我继续编写了一个在我的应用程序中处理它的函数。我不使用Stored Procs或Temp表,所以我不能使用你们中的一些人发布的有效答案。

5 个答案:

答案 0 :(得分:3)

您可以运行类似下面的存储过程的内容,以避免输入所有列名称。下面的示例假定为int,但您可以将键类型换出以用于任何数据类型。

create procedure [CloneRow]
    @tableName varchar(max),
    @keyName varchar(max),
    @oldKeyId int,
    @newTableId int output
as
    declare @sqlCommand nvarchar(max),
            @columnList varchar(max);

    select  @columnList = coalesce(@columnList + ',','') + sys.columns.name
    from    sys.columns
    where   object_name(sys.columns.object_id) = @tableName
        and sys.columns.name not in ( @keyName )
        and is_computed = 0;

    set @sqlCommand = 'insert into ' + @tableName + ' ( ' + @columnList + ') (' +
        'select ' + @columnList + ' from ' + @tableName + ' where ' + @keyName + ' = @oldKeyId )'
    exec sp_executesql @sqlCommand, N'@oldKeyId int', @oldKeyId = @oldKeyId
    select @newTableId = @@identity -- note scope_identity() won't work here!
GO

你这样称呼它:

declare @newOrderId int
exec [CloneRow] 'orderTable', 'orderId', 625911, @newOrderId output

答案 1 :(得分:2)

这不是最美丽的解决方案,但我认为它对您有用。首先,您使用“新”主键将数据选择到临时表中,然后从临时表中删除旧主键列,并使用临时表插入“克隆”行。

SELECT 
'PrimKey2' AS NewPrimKey,
*
INTO #TMP 
FROM PrimKeys 
WHERE PrimKey='PrimKey1';

ALTER TABLE #TMP DROP COLUMN PrimKey;

INSERT INTO PrimKeys
SELECT * FROM #TMP;

答案 2 :(得分:1)

首先,如果您需要对大量表执行泛型操作,那么动态SQL和系统表就是您的朋友。

除此之外,Hakan的解决方案将适用于非身份PK。我会把它收紧到:

SELECT * INTO #TMP 
FROM PrimKeys 
WHERE PrimKey='PrimKey1';

UPDATE #TMP SET PrimeKey = 'PrimeKey2';

INSERT INTO PrimKeys
SELECT * FROM #TMP;

对于身份PK,将上面的UPDATE更改为DROP COLUMN:

SELECT * INTO #TMP 
FROM PrimKeys 
WHERE PrimKey=101;

ALTER TABLE #TMP DROP COLUMN PrimeKey;

INSERT INTO PrimKeys
SELECT * FROM #TMP;

答案 3 :(得分:0)

不确定具有单个主键的“多个表”行是什么意思“。

根据定义,

PRIMARY KEYUNIQUE

要进行查询,您需要枚举所有列:

INSERT
INTO    PrimKeys (PrimKey, col1, col2, …)
SELECT  'PrimKey2' AS PrimKey, col1, col2, …
FROM    PrimKeys
WHERE   PrimKey = 'PrimKey1'

答案 4 :(得分:0)

如果您是从多个表进行克隆,最快的方法是使用存储过程,以便所有查询都保留在数据库中,并且您不需要为客户端和服务器之间的通信付出代价。 / p>

一旦你这样做,然后开始单元测试,看看进行操作需要多长时间。然后根据您获得的建议开始尝试更改它,看看您是否有任何改进。