将一行数据从一个表移动到另一个表?

17

我有两个具有相同列定义的表。我需要将其中一张表的一行移动(而不是复制)到另一张表中。在我使用 INSERT INTO/DELETE(在事务中)之前,是否有更聪明的方法?

SQL Server 2005

5个回答

32

对于 SQL Server 2005 及更高版本,尝试使用 OUTPUT 子句 (Transact-SQL)

DELETE OldTable
  OUTPUT DELETED.col1, DELETED.col2...
      INTO NewTable
  WHERE ID=...

工作示例:

DECLARE @OldTable table(col1 int, col2    varchar(5), col3 char(5), col4     datetime)
DECLARE @NewTable table(col1 int, column2 varchar(5), col3 int    , col_date char(23), extravalue int, othervalue varchar(5))
INSERT @OldTable VALUES (1 , 'AAA' ,'A'  ,'1/1/2010'           )
INSERT @OldTable VALUES (2 , 'BBB' ,'12' ,'2010-02-02 10:11:22')
INSERT @OldTable VALUES (3 , 'CCC' ,null ,null                 )
INSERT @OldTable VALUES (4 , 'B'   ,'bb' ,'2010-03-02'         )

DELETE @OldTable
    OUTPUT DELETED.col1
          ,DELETED.col2
          ,CASE
               WHEN ISNUMERIC(DELETED.col3)=1 THEN DELETED.col3 
               ELSE NULL END
          ,DELETED.col4
          ,CONVERT(varchar(5),DELETED.col1)+'!!'
        INTO @NewTable (col1, column2, col3, col_date, othervalue)
    OUTPUT 'Rows Deleted: ', DELETED.* --this line returns a result set shown in the OUTPUT below
    WHERE col1 IN (2,4)

SELECT * FROM @NewTable

输出:

               col1        col2  col3  col4
-------------- ----------- ----- ----- -----------------------
Rows Deleted:  2           BBB   12    2010-02-02 10:11:22.000
Rows Deleted:  4           B     bb    2010-03-02 00:00:00.000

(2 row(s) affected)

col1        column2 col3        col_date                extravalue  othervalue
----------- ------- ----------- ----------------------- ----------- ----------
2           BBB     12          Feb  2 2010 10:11AM     NULL        2!!
4           B       NULL        Mar  2 2010 12:00AM     NULL        4!!

(2 row(s) affected)

1
@KM:+1。我之前不知道这个方法。您会推荐使用这种方法而不是“INSERT”和“DELETE”吗? - Daniel Vassallo
1
每次我都会使用这个方法,而不是使用INSERT和DELETE。SQL Server可以更好地优化它,并且它保证您只插入和删除相同的行,不多也不少。 - KM.
3
我身体非常健康。我提出这个问题实在是不抱任何希望,只是想在采取“我知道的方法”之前向聪明人请教一下。得到如此好的答案真是太令人满意了,更让人满意的是看到其他许多人跟我一样,从我的问题中学到了这种“新”技巧。非常感谢。 - lance
@KM。这个话题有点老了,但如果您需要移动行且不包括其中一列并添加新列,您仍然建议使用此方法吗? - joshmax
2
@Max,如果你需要捕获已删除的行,那么使用OUTPUT是最好的方法。如果你需要另外一列,我会在使用DELETE OUTPUT填充行后进行UPDATE并联接它。 - KM.
显示剩余3条评论

3

您可以尝试使用以下语句:Insert into abc(a,b,c) select(a,b,c) from def。

执行以上操作将会把def表的a、b、c列插入到abc表的a、b、c列中。在插入完成之后,可以根据需要运行delete table、drop table或truncate等命令来清空表。

以下是示例:

Begin
    Begin try

         Begin Transaction

               Insert into emp(name, department, salary)                    
                       Select empName,empDepartment,empSal from employees
                       Where  employees.empID = 211

               Truncate table employees

          End Transaction  

    End try

    Begin Catch

         if @@Error > 0
              Rollback Transaction

    End Catch

End

0
在SQL中没有MOVE命令这种东西。 你需要先从表1插入到表2, 然后再从表1删除副本。

5
OP正在使用SQL Server 2005,因此OUTPUT子句(Transact-SQL)可以在一条命令中完成,详见我的回答... - KM.

0

不,你基本上只能在事务中使用插入和删除操作。


4
OP正在使用SQL Server 2005,因此OUTPUT语句(T-SQL)可以在单个命令中完成,详见我的回答... - KM.

0
INSERT dbo.newtable(
      name,
      department,
      Salary
) SELECT 
            name,
            FirstName,
            Lastname
      FROM    (
           DELETE dbo.oldtable
           OUTPUT
                   DELETED.name,
                   DELETED.department,
                   DELETED.Salary
           WHERE ID  IN ( 1001, 1003, 1005 )
      ) AS RowsToMove  

SELECT * FROM dbo.newtable
SELECT * FROM dbo.oldtable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接