INSERT (Transact-SQL)

在資料表或檢視表中加入新的資料列。

主題連結圖示Transact-SQL 語法慣例

語法

[ WITH <common_table_expression> [ ,...n ] ]
INSERT 
    [ TOP ( expression ) [ PERCENT ] ] 
    [ INTO] 
    { <object> | rowset_function_limited 
      [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
    }
{
    [ ( column_list ) ] 
    [ <OUTPUT Clause> ]
    { VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) 
    | derived_table 
    | execute_statement 
    } 
} 
    | DEFAULT VALUES 
[; ]

<object> ::=
{ 
    [ server_name . database_name . schema_name . 
      | database_name .[ schema_name ] . 
      | schema_name . 
    ]
        table_or_view_name
}

引數

  • WITH <common_table_expression>
    指定定義在 INSERT 陳述式範圍內的暫存具名結果集,也稱為一般資料表運算式。這個結果集是從 SELECT 陳述式衍生而來。

    一般資料表運算式也可以搭配 SELECT、DELETE、UPDATE 和 CREATE VIEW 等陳述式來使用。如需詳細資訊,請參閱<WITH common_table_expression (Transact-SQL)>。

  • TOP (expression) [ PERCENT ]
    指定將插入的隨機資料列數或百分比。expression 可以是一個數字,也可以是資料列的百分比。搭配 INSERT、UPDATE 或 DELETE 使用的 TOP 運算式所參考的資料列並不依照任何順序來排列。

    TOP 中用來分隔 expression 的括號,在 INSERT、UPDATE 和 DELETE 陳述式中是必要的。如需詳細資訊,請參閱<TOP (Transact-SQL)>。

  • INTO
    這是一個選擇性的關鍵字,您可以在 INSERT 和目標資料表之間使用它。
  • server_name
    這是資料表或檢視表所在的伺服器名稱 (利用 OPENDATASOURCE 函數做為伺服器名稱)。如果指定 server_name,則需要 database_nameschema_name
  • database_name
    這是資料庫的名稱。
  • schema_name
    這是資料表或檢視表所屬的結構描述名稱。
  • table_or view_name
    這是將接收資料之資料表或檢視表的名稱。

    table 變數在它本身的範圍內,可用來做為 INSERT 陳述式中的資料表來源。

    table_or_view_name 所參考的檢視表必須能夠更新,且必須參考檢視表的 FROM 子句中正好一個基底資料表。例如,指向多資料表檢視表的 INSERT,必須使用只參考單一基底資料表的各個資料行之 column_list。如需有關可更新檢視表的詳細資訊,請參閱<CREATE VIEW (Transact-SQL)>。

  • WITH ( <table_hint_limited> [... n ] )
    指定目標資料表允許使用的一或多個資料表提示。WITH 關鍵字和括號都是必要的。

    不允許使用 READPAST、NOLOCK 和 READUNCOMMITTED。如需有關資料表提示的詳細資訊,請參閱<資料表提示 (Transact-SQL)>。

    ms174335.note(zh-tw,SQL.90).gif重要事項:
    SQL Server 未來的版本將移除指定 INSERT 陳述式的目標資料表之 HOLDLOCK、SERIALIZABLE、READCOMMITTED、REPEATABLEREAD 或 UPDLOCK 提示的功能。這些提示不會影響 INSERT 陳述式的效能。請避免在新的開發工作中使用它們,並規劃修改目前在使用它們的應用程式。

    指定 INSERT 陳述式目標資料表之 TABLOCK 提示的效果,與指定 TABLOCKX 提示相同。獨佔鎖定是在資料表上取得的。

  • (column_list)
    這是要插入資料的一或多個資料行所組成的清單。column_list 必須括在括號中,而且是以逗號分隔。

    如果資料行不在 column_list 中,SQL Server 2005 Database Engine 必須能夠提供以資料行定義為基礎的值;否則,便無法載入這個資料列。如果資料行符合下列條件,Database Engine 會自動提供資料行值:

    • 有 IDENTITY 屬性。使用下一個累加識別值。
    • 有預設值。使用資料行的預設值。
    • timestamp 資料類型。使用目前的時間戳記值。
    • 可為 Null。使用 Null 值。
    • 這是計算資料行。使用計算的值。

    當您將明確的值插入識別欄位時,必須使用 column_list 和 VALUES 清單,資料表的 SET IDENTITY_INSERT 選項必須是 ON。

  • OUTPUT 子句
    在插入作業中,傳回插入的資料列。在參考本機資料分割檢視、分散式資料分割檢視或遠端資料表的 DML 陳述式中,以及在包含 execute_statement 的 INSERT 陳述式中,都不支援 OUTPUT 子句
  • VALUES
    導入要插入的資料值清單。column_list (如果指定的話) 或資料表中的每個資料行,都必須有一個資料值。這份值清單必須括在括號中。

    如果 VALUE 清單中的值與資料表中的資料行順序不同,或每個資料表資料行並未各有一個值,就必須利用 column_list 來明確指定儲存每個內送值的資料行。

  • DEFAULT
    強制 Database Engine 載入定義給資料行的預設值。如果資料行的預設值不存在,且資料行允許 Null 值,就會插入 NULL。如果是用 timestamp 資料類型來定義的資料行,就會插入下一個時間戳記值。識別欄位的 DEFAULT 無效。
  • expression
    這是一個常數、變數或運算式。運算式不能包含 SELECT 或 EXECUTE 陳述式。
  • derived_table
    這是傳回要載入資料表之資料列的任何有效 SELECT 陳述式。SELECT 陳述式不能包含一般資料表運算式 (CTE)。
  • execute_statement
    這是任何隨著 SELECT 或 READTEXT 陳述式而傳回資料的有效 EXECUTE 陳述式。SELECT 陳述式不能包含 CTE。

    如果 execute_statement 是搭配 INSERT 來使用,每個結果集都必須相容於資料表或 column_list 中的資料行。

    execute_statement 可用來在相同伺服器或遠端伺服器中執行預存程序。這會執行在遠端伺服器中的程序,結果集會傳回本機伺服器,且會載入本機伺服器的資料表中。

    SQL Server 2008 會變更針對回送連結伺服器執行之 INSERT...EXECUTE 陳述式的交易語意。在 SQL Server 2005 中,不支援這個狀況而且會導致錯誤。在 SQL Server 2008 中,當連接沒有啟用 Multiple Active Result Sets (MARS) 時,INSERT...EXECUTE 陳述式可以針對回送連結伺服器執行。當連接啟用 MARS 時,其行為就與 SQL Server 2005 相同。

    如果 execute_statement 是隨著 READTEXT 陳述式而傳回資料,則每個 READTEXT 陳述式都可以傳回最多 1 MB (1024 KB) 的資料。execute_statement 也可用來搭配擴充程序。execute_statement 會插入擴充程序主要執行緒所傳回的資料;不過,不會插入主要執行緒以外之執行緒的輸出。

  • DEFAULT VALUES
    強制新的資料列包含定義給每個資料行的預設值。

備註

INSERT 會將新資料列附加至資料表。若要取代資料表中的資料,您必須利用 DELETETRUNCATE TABLE 陳述式來清除現有的資料,之後,才能利用 INSERT 來載入新的資料。若要修改現有資料列中的資料行值,請使用 UPDATE。您可以建立一份新資料表,之後再利用 SELECT 陳述式的 INTO 選項,在單一步驟中,在其中載入資料。

利用 uniqueidentifier 資料類型來建立的資料行會儲存特殊格式的 16 位元組二進位值。這不像識別欄位,Database Engine 不會自動產生 uniqueidentifier 資料類型的資料行值。在插入作業期間,uniqueidentifier 資料行可以使用 uniqueidentifier 資料類型的變數及 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 格式的字串常數 (36 個字元,包括連字號,其中 x 是 0-9 或 a-f 範圍內的十六進位數字)。例如,6F9619FF-8B86-D011-B42D-00C04FC964FF 便是 uniqueidentifier 變數或資料行的有效值。請利用 NEWID() 函數來取得全域唯一識別碼 (GUID)。

針對本機和遠端資料分割檢視來進行的 INSERT 陳述式,其 SET ROWCOUNT 選項的設定會被忽略。另外,當相容性層級設為 80 或以上時,也不支援在 Database Engine 中針對遠端資料表發出的 INSERT 陳述式使用這個選項。

當 INSERT 陳述式遇到在運算式評估期間發生算術錯誤 (溢位、除以零或區域錯誤) 時,Database Engine 會依照 SET ARITHABORT 設為 ON 的方式來處理這些錯誤。批次的其餘部分會停止運作,且會傳回錯誤訊息。

插入資料列的規則

當您插入資料列時,適用下列規則:

  • 如果正在將值載入含 charvarcharvarbinary 資料類型的資料行,填補或截斷尾端空白 (charvarchar 是空格, varbinary 是零) 取決於建立資料表時定義給資料行的 SET ANSI_PADDING 設定。如需詳細資訊,請參閱<SET ANSI_PADDING (Transact-SQL)>。
    下表顯示 SET ANSI_PADDING OFF 的預設作業。

    資料類型 預設作業

    char

    值填補空格到定義的資料行寬度。

    varchar

    移除尾端空格到最後一個非空格字元,或到只由空格組成的字串的一個空格字元。

    varbinary

    移除尾端零。

  • 如果將空字串 (' ') 載入 varchartext 資料類型的資料行,預設作業便是載入長度為零的字串。

  • 如果 INSERT 陳述式違反條件約束或規則,或它有不相容於資料行資料類型的值,陳述式便會失敗,Database Engine 會顯示一則錯誤訊息。

  • 將 Null 值插入 textimage 資料行不會建立有效的文字指標,也不會預先配置 8KB 文字頁面。如需有關插入 textimage 資料的詳細資訊,請參閱<使用 text、ntext 與 image 函數>。

  • 如果 INSERT 利用 SELECT 或 EXECUTE 來載入多個資料列,當載入的值違反規則或條件約束時,整個陳述式便會停止運作,不會載入任何資料列。

  • 當您在 Database Engine 的遠端執行個體中將值插入資料表時,如果並未完整指定所有資料表的所有值,您必須識別要插入指定值的資料行。

在 INSERT 動作上使用 INSTEAD OF 觸發程序

當定義資料表或檢視表之 INSERT 動作的 INSTEAD OF 觸發程序時,會執行觸發程序,而不是 INSERT 陳述式。舊版的 SQL Server 只支援 INSERT 及其他資料修改陳述式所定義的 AFTER 觸發程序。如需有關 INSTEAD OF 觸發程序的詳細資訊,請參閱<CREATE TRIGGER (Transact-SQL)>。

將值插入使用者定義類別資料行

您可以利用下列方式,在使用者定義類別資料行中插入值:

  • 提供使用者定義類別的值。

  • 只要使用者定義類別支援從這個類型進行隱含或明確的轉換,便在 SQL Server 2005 系統資料類型中提供一個值。下列範例會顯示如何從字串進行明確的轉換,以便在使用者定義類別 Point 的資料行中插入一個值。

    INSERT INTO Cities (Location)
    VALUES ( CONVERT(Point, '12.3:46.2') );
    

    您不需要執行明確的轉換,便可以提供二進位值,因為所有使用者定義類別都隱含從二進位轉換的功能。如需有關轉換和使用者定義類別的詳細資訊,請參閱<對使用者自訂類型執行作業>。

  • 呼叫傳回使用者定義類別值的使用者定義函數。下列範例會利用使用者定義函數 CreateNewPoint() 來建立使用者定義類別 Point 的新值,且將這個值插入 Cities 資料表中。

    INSERT INTO Cities (Location)
    VALUES ( dbo.CreateNewPoint(x, y) );
    

利用 OPENROWSET 和 BULK 來大量載入資料

在 SQL Server 2005 Database Engine 中,OPENROWSET 大量資料列集提供者所能使用的新資料表提示,會提供 INSERT 陳述式的下列大量載入最佳化:

  • 大量載入記錄 (將插入作業的記錄數目縮到最小)
  • 條件約束檢查可以設為 ON 或 OFF
  • 觸發程序的執行可以設為 ON 或 OFF

這些最佳化類似於 BULK INSERT 命令所能使用的最佳化。

當 INSERT 陳述式執行非空白資料表的大量載入時,會有下列其他效能增強功能:

  • 當在大量載入期間分割頁面時,並不需要完整記錄加入頁面的新資料列。
  • 如果資料表有非叢集索引,但沒有叢集索引,便必須完整記錄個別的索引資料列,不過,不需要完整記錄資料列。

如需詳細資訊,請參閱<OPENROWSET (Transact-SQL)>和<資料表提示 (Transact-SQL)>。

權限

需要目標資料表的 INSERT 權限。

INSERT 權限預設會授與系統管理員 (sysadmin) 固定伺服器角色、db_ownerdb_datawriter 固定資料庫角色的成員,以及資料表擁有者。系統管理員 (sysadmin)db_ownerdb_securityadmin 角色的成員,以及資料表擁有者,可以將權限轉讓給其他使用者。

若要設定 OPENROWSET 函數 BULK 選項來執行 INSERT,您必須是系統管理員 (sysadmin)bulkadmin 固定伺服器角色的成員。

範例

A. 使用簡式 INSERT 陳述式

下列範例會在 Production.UnitMeasure 資料表中插入一個資料列。由於提供了所有資料行的值,且依照資料表中資料行的相同順序來列出它們,因此,不需要在 column_list. 中指定資料行名稱。

USE AdventureWorks;
GO
INSERT INTO Production.UnitMeasure
VALUES (N'F2', N'Square Feet', GETDATE());
GO

B. 插入與資料表資料行順序不同的資料

下列範例會利用 column_list 來明確指定插入每個資料行的值。UnitMeasure 資料表中的資料行順序是 UnitMeasureCodeNameModifiedDate;不過,這些資料行不會依照 column_list 中的順序來列出。

USE AdventureWorks;
GO
INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode,
    ModifiedDate)
VALUES (N'Square Yards', N'Y2', GETDATE());
GO

C. 插入其值比資料行少的資料

下列範例會顯示如何將資料列插入含有自動產生值或有預設值的資料行之資料表中。INSERT 陳述式會插入包含部分 (而非全部) 資料行值的資料列。在最後一個 INSERT 陳述式中,並未指定任何資料行,只插入預設值。

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
    DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1 
(
    column_1 int IDENTITY, 
    column_2 varchar(30) 
        CONSTRAINT default_name DEFAULT ('my column default'),
    column_3 timestamp,
    column_4 varchar(40) NULL
);
GO
INSERT INTO dbo.T1 (column_4) 
    VALUES ('Explicit value');
INSERT INTO dbo.T1 (column_2, column_4) 
    VALUES ('Explicit value', 'Explicit value');
INSERT INTO dbo.T1 (column_2) 
    VALUES ('Explicit value');
INSERT INTO T1 DEFAULT VALUES; 
GO
SELECT column_1, column_2, column_3, column_4
FROM dbo.T1;
GO

D. 將資料插入含識別欄位的資料表

下列範例會顯示將資料插入識別欄位的不同方法。前兩個 INSERT 陳述式允許可用來產生新資料列的識別值。第三個 INSERT 陳述式利用 SET IDENTITY_INSERT 陳述式來覆寫資料行的 IDENTITY 屬性,且會將明確的值插入識別欄位中。

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
    DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1 ( column_1 int IDENTITY, column_2 VARCHAR(30));
GO
INSERT T1 VALUES ('Row #1');
INSERT T1 (column_2) VALUES ('Row #2');
GO
SET IDENTITY_INSERT T1 ON;
GO
INSERT INTO T1 (column_1,column_2) 
    VALUES (-99, 'Explicit identity value');
GO
SELECT column_1, column_2
FROM T1;
GO

E. 利用 NEWID() 來將資料插入 uniqueidentifier 資料行

下列範例會利用 NEWID() 函數來取得 column_2 的 GUID。這不像識別欄位,Database Engine 並不會如第二個 INSERT 陳述式所示,自動產生 uniqueidentifier 資料類型的資料行值。

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
    DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1 
(
    column_1 int IDENTITY, 
    column_2 uniqueidentifier,
);
GO
INSERT INTO dbo.T1 (column_2) 
    VALUES (NEWID());
INSERT INTO T1 DEFAULT VALUES; 
GO
SELECT column_1, column_2
FROM dbo.T1;
GO

F. 利用檢視表將資料插入資料表

下列範例在 INSERT 陳述式中指定檢視表名稱;不過,新資料列會插入檢視表的基礎資料表中。INSERT 陳述式中 VALUES 清單的順序必須符合檢視表的資料行順序。

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
    DROP TABLE dbo.T1;
GO
IF OBJECT_ID ('dbo.V1', 'V') IS NOT NULL
    DROP VIEW dbo.V1;
GO
CREATE TABLE T1 ( column_1 int, column_2 varchar(30));
GO
CREATE VIEW V1 AS 
SELECT column_2, column_1 
FROM T1;
GO
INSERT INTO V1 
    VALUES ('Row 1',1);
GO
SELECT column_1, column_2 
FROM T1;
GO
SELECT column_1, column_2
FROM V1;
GO

G. 利用 SELECT 和 EXECUTE 選項來插入資料

下列範例會顯示從一份資料表中取得資料,再將它插入另一份資料表的三種不同方法。每個方法都是以多資料表的 SELECT 陳述式為基礎,SELECT 陳述式的資料行清單包括一個運算式及一個常值。

第一個 INSERT 陳述式利用 SELECT 陳述式來直接擷取來源資料表 (EmployeeSalesPersonContact) 的資料,且會將結果集儲存在 EmployeeSales 資料表中。第二個 INSERT 會執行包含 SELECT 陳述式的預存程序,第三個 INSERTSELECT 陳述式當做一個常數字串來執行。

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL
    DROP TABLE dbo.EmployeeSales;
GO
IF OBJECT_ID ('dbo.uspGetEmployeeSales', 'P') IS NOT NULL
    DROP PROCEDURE uspGetEmployeeSales;
GO
CREATE TABLE dbo.EmployeeSales
( DataSource   varchar(20) NOT NULL,
  EmployeeID   varchar(11) NOT NULL,
  LastName     varchar(40) NOT NULL,
  SalesDollars money NOT NULL
);
GO
CREATE PROCEDURE dbo.uspGetEmployeeSales 
AS 
    SET NOCOUNT ON;
    SELECT 'PROCEDURE', e.EmployeeID, c.LastName, 
        sp.SalesYTD 
    FROM HumanResources.Employee AS e 
        INNER JOIN Sales.SalesPerson AS sp  
        ON e.EmployeeID = sp.SalesPersonID 
        INNER JOIN Person.Contact AS c
        ON e.ContactID = c.ContactID
    WHERE e.EmployeeID LIKE '2%'
    ORDER BY e.EmployeeID, c.LastName;
GO
--INSERT...SELECT example
INSERT dbo.EmployeeSales
    SELECT 'SELECT', e.EmployeeID, c.LastName, sp.SalesYTD 
    FROM HumanResources.Employee AS e
        INNER JOIN Sales.SalesPerson AS sp
        ON e.EmployeeID = sp.SalesPersonID 
        INNER JOIN Person.Contact AS c
        ON e.ContactID = c.ContactID
    WHERE e.EmployeeID LIKE '2%'
    ORDER BY e.EmployeeID, c.LastName;
GO
--INSERT...EXECUTE procedure example
INSERT EmployeeSales 
EXECUTE uspGetEmployeeSales;
GO
--INSERT...EXECUTE('string') example
INSERT EmployeeSales 
EXECUTE 
('
SELECT ''EXEC STRING'', e.EmployeeID, c.LastName, 
    sp.SalesYTD 
    FROM HumanResources.Employee AS e 
        INNER JOIN Sales.SalesPerson AS sp 
        ON e.EmployeeID = sp.SalesPersonID 
        INNER JOIN Person.Contact AS c
        ON e.ContactID = c.ContactID
    WHERE e.EmployeeID LIKE ''2%''
    ORDER BY e.EmployeeID, c.LastName
');
GO
--Show results.
SELECT DataSource,EmployeeID,LastName,SalesDollars
FROM dbo.EmployeeSales;
GO

H. 利用 TOP 子句來插入資料

下列範例會建立 NewEmployee 資料表,且會將 Employee 資料表的前 10 名員工的地址資料插入其中。之後,便會執行 SELECT 陳述式來驗證 NewEmployee 資料表的內容。

USE AdventureWorks;
GO
IF OBJECT_ID (N'HumanResources.NewEmployee', N'U') IS NOT NULL
    DROP TABLE HumanResources.NewEmployee;
GO
CREATE TABLE HumanResources.NewEmployee
(
    EmployeeID int NOT NULL,
    LastName nvarchar(50) NOT NULL,
    FirstName nvarchar(50) NOT NULL,
    Phone Phone NULL,
    AddressLine1 nvarchar(60) NOT NULL,
    City nvarchar(30) NOT NULL,
    State nchar(3) NOT NULL, 
    PostalCode nvarchar(15) NOT NULL,
    CurrentFlag Flag
);
GO
INSERT TOP (10) INTO HumanResources.NewEmployee 
    SELECT
       e.EmployeeID, c.LastName, c.FirstName, c.Phone,
       a.AddressLine1, a.City, sp.StateProvinceCode, 
       a.PostalCode, e.CurrentFlag
    FROM HumanResources.Employee e
        INNER JOIN HumanResources.EmployeeAddress AS ea
        ON e.EmployeeID = ea.EmployeeID
        INNER JOIN Person.Address AS a
        ON ea.AddressID = a.AddressID
        INNER JOIN Person.StateProvince AS sp
        ON a.StateProvinceID = sp.StateProvinceID
        INNER JOIN Person.Contact as c
        ON e.ContactID = c.ContactID;
GO
SELECT  EmployeeID, LastName, FirstName, Phone,
        AddressLine1, City, State, PostalCode, CurrentFlag
FROM HumanResources.NewEmployee;
GO

I. 搭配 INSERT 陳述式使用 OUTPUT

下列範例將資料列插入 ScrapReason 資料表中,且利用 OUTPUT 子句,將陳述式的結果傳回 @MyTableVartable 變數中。由於 ScrapReasonID 資料行定義了 IDENTITY 屬性,因此,INSERT 陳述式並未指定這個資料行的值。不過請注意,Database Engine 針對這個資料行所產生的值,會在 INSERTED.ScrapReasonID 資料行的 OUTPUT 子句中傳回。

USE AdventureWorks;
GO
DECLARE @MyTableVar table( ScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT ScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

J. 搭配 INSERT 陳述式使用 WITH 一般資料表運算式

下列範例會建立 NewEmployee 資料表。一般資料表運算式 (EmployeeTemp) 會定義要插入 NewEmployee 資料表的資料列。INSERT 陳述式會在一般資料表運算式中參考資料行。

USE AdventureWorks;
GO
IF OBJECT_ID (N'HumanResources.NewEmployee', N'U') IS NOT NULL
    DROP TABLE HumanResources.NewEmployee;
GO
CREATE TABLE HumanResources.NewEmployee
(
    EmployeeID int NOT NULL,
    LastName nvarchar(50) NOT NULL,
    FirstName nvarchar(50) NOT NULL,
    Phone Phone NULL,
    AddressLine1 nvarchar(60) NOT NULL,
    City nvarchar(30) NOT NULL,
    State nchar(3) NOT NULL, 
    PostalCode nvarchar(15) NOT NULL,
    CurrentFlag Flag
);
GO
WITH EmployeeTemp (EmpID, LastName, FirstName, Phone, 
                   Address, City, StateProvince, 
                   PostalCode, CurrentFlag)
AS (SELECT 
        e.EmployeeID, c.LastName, c.FirstName, c.Phone,
        a.AddressLine1, a.City, sp.StateProvinceCode, 
        a.PostalCode, e.CurrentFlag
    FROM HumanResources.Employee e
        INNER JOIN HumanResources.EmployeeAddress AS ea
        ON e.EmployeeID = ea.EmployeeID
        INNER JOIN Person.Address AS a
        ON ea.AddressID = a.AddressID
        INNER JOIN Person.StateProvince AS sp
        ON a.StateProvinceID = sp.StateProvinceID
        INNER JOIN Person.Contact as c
        ON e.ContactID = c.ContactID
    )
INSERT INTO HumanResources.NewEmployee 
    SELECT EmpID, LastName, FirstName, Phone, 
           Address, City, StateProvince, PostalCode, CurrentFlag
    FROM EmployeeTemp;
GO

K. 搭配識別和計算資料行使用 OUTPUT

下列範例會建立 EmployeeSales 資料表,之後再利用含有 SELECT 陳述式的 INSERT 陳述式來擷取來源資料表中的資料,以插入幾個資料列。EmployeeSales 資料表包含一個識別欄位 (EmployeeID) 和一個計算資料行 (ProjectedSales)。由於這些值都是 Database Engine 在插入作業期間所產生的,因此,這些資料行都不能定義在 @MyTableVar 中。

USE AdventureWorks ;
GO
IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL
    DROP TABLE dbo.EmployeeSales;
GO
CREATE TABLE dbo.EmployeeSales
( EmployeeID   int IDENTITY (1,5)NOT NULL,
  LastName     nvarchar(20) NOT NULL,
  FirstName    nvarchar(20) NOT NULL,
  CurrentSales money NOT NULL,
  ProjectedSales AS CurrentSales * 1.10 
);
GO
DECLARE @MyTableVar table(
  LastName     nvarchar(20) NOT NULL,
  FirstName    nvarchar(20) NOT NULL,
  CurrentSales money NOT NULL
  );

INSERT INTO dbo.EmployeeSales (LastName, FirstName, CurrentSales)
  OUTPUT INSERTED.LastName, 
         INSERTED.FirstName, 
         INSERTED.CurrentSales
  INTO @MyTableVar
    SELECT c.LastName, c.FirstName, sp.SalesYTD
    FROM HumanResources.Employee AS e
        INNER JOIN Sales.SalesPerson AS sp
        ON e.EmployeeID = sp.SalesPersonID 
        INNER JOIN Person.Contact AS c
        ON e.ContactID = c.ContactID
    WHERE e.EmployeeID LIKE '2%'
    ORDER BY c.LastName, c.FirstName;

SELECT LastName, FirstName, CurrentSales
FROM @MyTableVar;
GO
SELECT EmployeeID, LastName, FirstName, CurrentSales, ProjectedSales
FROM dbo.EmployeeSales;
GO

請參閱

參考

BULK INSERT (Transact-SQL)
CREATE TABLE (Transact-SQL)
DELETE (Transact-SQL)
EXECUTE (Transact-SQL)
FROM (Transact-SQL)
IDENTITY (屬性) (Transact-SQL)
NEWID (Transact-SQL)
SELECT (Transact-SQL)
SET ROWCOUNT (Transact-SQL)
UPDATE (Transact-SQL)

其他資源

將資料插入資料表

說明及資訊

取得 SQL Server 2005 協助