Sql-Server

如何使用 SELECT INTO 複製表但忽略 IDENTITY 屬性?

  • September 22, 2020

我有一個帶有標識列的表說:

create table with_id (
id int identity(1,1),
val varchar(30)
);

眾所周知,這

select * into copy_from_with_id_1 from with_id;

導致 copy_from_with_id_1 在 id 上也有身份。

以下堆棧溢出問題提到明確列出所有列。

我們試試吧

select id, val into copy_from_with_id_2 from with_id;

糟糕,即使在這種情況下 id 也是一個標識列。

我想要的是一張像

create table without_id (
id int,
val varchar(30)
);

來自線上書籍

new_table 的格式是通過評估選擇列表中的表達式來確定的。new_table 中的列是按照選擇列表指定的順序創建的。new_table 中的每一列與選擇列表中的相應表達式具有相同的名稱、數據類型、可空性和值。除非在“備註”部分的“使用標識列”中定義的條件下,否則會轉移列的 IDENTITY 屬性。

下頁:

將現有標識列選擇到新表中時,新列將繼承 IDENTITY 屬性,除非以下條件之一為真:

  • SELECT 語句包含連接、GROUP BY 子句或聚合函式。
  • 使用 UNION 連接多個 SELECT 語句。
  • 標識列在選擇列表中多次列出。
  • 標識列是表達式的一部分。
  • 標識列來自遠端數據源。

如果其中任何一個條件為真,則創建的列不是 NULL,而不是繼承 IDENTITY 屬性。如果新表中需要標識列但這樣的列不可用,或者您需要與源標識列不同的種子或增量值,請使用 IDENTITY 函式在選擇列表中定義該列。請參閱下面範例部分中的“使用 IDENTITY 函式創建標識列”。

所以……你理論上可以逃脫:

select id, val 
into copy_from_with_id_2 
from with_id

union all

select 0, 'test_row' 
where 1 = 0;

註釋此程式碼以對其進行解釋很重要,以免下次有人查看它時將其刪除。

引用自:https://dba.stackexchange.com/questions/916