插入...选择*,如何忽略身份?

时间:2008-09-23 18:00:56

标签: sql sql-server

我有一个临时表,其中包含具体表T的确切结构。它是这样创建的:

select top 0 * into #tmp from T

处理并将内容填入#tmp后,我想将内容复制回T,如下所示:

insert into T select * from #tmp

只要T没有标识列,这是可以的,但在我的情况下确实如此。当我复制到#tmp时,有什么办法可以忽略T的自动增量标识列吗?我的动机是避免在Insert Into列表中拼出每个列名。

编辑:切换identity_insert不起作用,因为#tmp中的pkeys可能会与T中的pkeys发生冲突,如果行被插入到我脚本之外的T中,那就是{{1}首先自动递增pkey以与T同步。

9 个答案:

答案 0 :(得分:13)

SET IDENTITY_INSERT ON

INSERT命令

SET IDENTITY_INSERT OFF

答案 1 :(得分:9)

因为无论如何都会在插入过程中生成标识,你可以在将数据插回T之前从#tmp中删除这个列吗?

alter table #tmp drop column id

UPD:以下是我在SQL Server 2008中测试的一个示例:

create table T(ID int identity(1,1) not null, Value nvarchar(50))
insert into T (Value) values (N'Hello T!')
select top 0 * into #tmp from T
alter table #tmp drop column ID
insert into #tmp (Value) values (N'Hello #tmp')
insert into T select * from #tmp
drop table #tmp
select * from T
drop table T

答案 2 :(得分:4)

查看答案herehere

select * into without_id from with_id
union all
select * from with_id where 1 = 0

原因:

  

当在新表中选择现有标识列时,新列将继承IDENTITY属性,除非满足下列条件之一:

     
      
  • SELECT语句包含连接,GROUP BY子句或聚合函数。
  •   
  • 使用UNION连接多个SELECT语句。
  •   
  • 标识列在选择列表中列出多次。
  •   
  • 标识列是表达式的一部分。
  •   
  • 标识列来自远程数据源。
  •   
     

如果满足其中任何一个条件,则会创建NOT NULL而不是继承IDENTITY属性。如果新表中需要标识列但是此列不可用,或者您希望种子或增量值与源标识列不同,请使用IDENTITY函数在选择列表中定义列。请参阅下面的示例部分中的“使用IDENTITY函数创建标识列”。

所有赠送金额均转入Eric Humphreybernd_k

答案 3 :(得分:1)

set identity_insert on

使用此功能。

答案 4 :(得分:1)

不是SELECT * - 如果你选择了每一列而不是身份,那就没问题了。我能看到的唯一方法是你可以通过动态构建INSERT语句来实现这一点。

答案 5 :(得分:1)

只需列出要重新插入的列,就不应该使用select *。如果您不想输入它们,只需从对象浏览器中拖动它们(如果展开表并拖动单词,列,您将获得所有这些,只需删除id列)

答案 6 :(得分:0)

可以在“T.ID =#tmp.ID”的“更新”工作吗?

答案 7 :(得分:0)

INSERT INTO #Table SELECT MAX(Id)+ ROW_NUMBER()OVER(ORDER BY Id)

答案 8 :(得分:-1)

  
      
  1. 它让我有机会在插入
  2. 之前预览数据   
  3. 作为计算的一部分,我在临时表之间加入;临时表允许我专注于我正在使用的确切设置数据。我想就是这样。有什么建议/意见吗?
  4.   

对于第1部分,正如Kolten在其中一条评论中所提到的,将您的语句封装在事务中并添加参数以在显示和提交之间切换将满足您的需求。对于第2部分,我需要查看您正在尝试的“计算”。将数据限制到临时表可能会使情况变得复杂。