SQL Server向表中插入數(shù)據(jù)

使用 INSERT 和 VALUES 插入行

INSERT 語句可向表中添加一個或多個新行。在簡化處理中,INSERT 具有以下格式:

INSERT [INTO] table_or_view [(column_list)] VALUES(data_values)
  • column_list 是列名的列表,列名以逗號分隔,用于指定為其提供數(shù)據(jù)的列。如果未指定 column_list,表或視圖中的所有列都將接收到數(shù)據(jù)。當(dāng) column_list 未指定表或視圖中的所有列時,系統(tǒng)會將默認值(如果為列定義了默認值)或 NULL 插入未在列表中指定的任一列。未在列列表中指定的所有列必須允許空值或分配了默認值。
  • VALUES 關(guān)鍵字為表的某一行或多個行指定值。這些值指定為逗號分隔的標(biāo)量表達式列表,表達式的數(shù)據(jù)類型、精度和小數(shù)位數(shù)必須與列的列表中對應(yīng)列一致,或者可以隱式轉(zhuǎn)換為列的列表中對應(yīng)列。

INSERT 語句不指定下列類型列的值,因為 SQL Server 數(shù)據(jù)庫引擎將為這些列生成值:

  • 具有 timestamp 數(shù)據(jù)類型。使用當(dāng)前的時間戳值。
  • 具有默認值的列,此默認值用 NEWID 函數(shù)生成唯一的 GUID 值。
  • 可以為 Null。使用 Null 值。
  • 標(biāo)識列。標(biāo)識列具有 IDENTITY 屬性的列,此屬性為該列生成值。
  • 計算列。計算列是指定義為通過 CREATE TABLE 語句中一個或多個其他列計算的表達式的虛擬列,例如:
CREATE TABLE TestTable
  (ColA INT PRIMARY KEY,
   ColB INT NOT NULL,
   ColC AS (ColA + ColB) * 2);

鎖定行為
??INSERT 語句總是在其修改的表上獲取排他 (X) 鎖并在事務(wù)完成之前持有該鎖。使用排他鎖(X 鎖)時,任何其他事務(wù)都無法修改數(shù)據(jù);僅在使用 NOLOCK 提示或未提交讀隔離級別時才會進行讀取操作。

日志記錄行為
??INSERT 語句始終完全記入日志,只有在將 OPENROWSET 函數(shù)與 BULK 關(guān)鍵字一起使用或者在使用 INSERT INTO <target_table> SELECT <columns> FROM <source_table> 時除外。這些操作可進行最小日志記錄。

【示例】
??以下示例顯示了如何將行插入包含自動生成值或具有默認值的列的表中。INSERT 語句插入一些行,這些行只有部分列包含值。在最后一個 INSERT 語句中,未指定列并只插入了默認值。

USE AdventureWorks2008R2;
GO
IF OBJECT_ID ('dbo.T1', 'U') IS NOT NULL
    DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1 
(
    column_1 AS 'Computed column ' + column_2, 
    column_2 varchar(30) 
        CONSTRAINT default_name DEFAULT ('my column default'),
    column_3 rowversion,
    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

查詢結(jié)果如下:

column_1                                       column_2                       column_3   column_4
---------------------------------------------- ------------------------------ ---------- --------------------
Computed column my column default              my column default              0x00000000 Explicit value
Computed column Explicit value                 Explicit value                 0x00000000 Explicit value
Computed column Explicit value                 Explicit value                 0x00000000 NULL
Computed column my column default              my column default              0x00000000 NULL

使用 INSERT 和 SELECT 子查詢插入行

INSERT 語句中的 SELECT 子查詢可用于將一個或多個表或視圖中的值添加到另一個表中。使用 SELECT 子查詢還可以同時插入多行。
??子查詢的選擇列表必須與 INSERT 語句的列列表匹配。如果沒有指定列列表,選擇列表必須與正在其中執(zhí)行插入操作的表或視圖的列匹配。
??在以下示例中,INSERT 語句將Sales.SalesReason 表中 SalesReason 為 Marketing 的所有行中的一些數(shù)據(jù)插入到一個單獨的表中:

USE AdventureWorks2008R2;
GO
CREATE TABLE MySalesReason (
    SalesReasonID int NOT NULL,
    Name nvarchar(50),
    ModifiedDate datetime);
GO
INSERT INTO MySalesReason
    SELECT SalesReasonID, Name, ModifiedDate
    FROM AdventureWorks2008R2.Sales.SalesReason
    WHERE ReasonType = N'Marketing';
GO

使用 SELECT INTO 插入行

SELECT INTO 語句用于創(chuàng)建一個新表,并用 SELECT 語句的結(jié)果集填充該表。SELECT INTO 可將幾個表或視圖中的數(shù)據(jù)組合成一個表。也可用于創(chuàng)建一個包含選自鏈接服務(wù)器的數(shù)據(jù)的新表。
??新表的結(jié)構(gòu)由選擇列表中表達式的屬性定義。下面的示例中,從多個雇員和與地址相關(guān)的表中選擇七列來創(chuàng)建表 dbo.EmployeeAddresses。

USE AdventureWorks2008R2;
GO
SELECT c.FirstName, c.LastName, e.JobTitle, a.AddressLine1, a.City, 
    sp.Name AS [State/Province], a.PostalCode
INTO dbo.EmployeeAddresses
FROM Person.Person AS c
    JOIN HumanResources.Employee AS e 
    ON e.BusinessEntityID = c.BusinessEntityID
    JOIN Person.BusinessEntityAddress AS bea
    ON e.BusinessEntityID = bea.BusinessEntityID
    JOIN Person.Address AS a
    ON bea.AddressID = a.AddressID
    JOIN Person.StateProvince as sp 
    ON sp.StateProvinceID = a.StateProvinceID;
GO

SELECT INTO 不使用源表的分區(qū)方案。而新表是在默認文件組中創(chuàng)建的,若要向已分區(qū)表插入行,首先必須創(chuàng)建已分區(qū)表,然后再使用 INSERT INTO…SELECT FROM 語句。
??使用 SELECT INTO 語句創(chuàng)建新表時,F(xiàn)ILESTREAM 屬性不傳輸。FILESTREAM BLOB 作為 varbinary(max) BLOB 復(fù)制并存儲在新表中。如果 FILESTREAM BLOB 超過 2 GB,則將引發(fā)以下錯誤消息,并且語句停止:“正嘗試增長 LOB,使其超過允許的最大大小(2147483647 個字節(jié))”。

使用INSERT EXEC語句插入行

INSERT [INTO] table_name|table_variable [(column_list )] execute_statement
  • table_name:表名,可以是永久表或臨時表
  • table_variable:表變量(SQL Server不可用)
  • execute_statement:任何有效的 EXECUTE 語句,它使用 SELECT 或 READTEXT 語句返回數(shù)據(jù)。
  • 如果 execute_statement 使用 INSERT,則每個結(jié)果集必須與表或 column_list 中的列兼容。
  • 如果 execute_statement 使用 READTEXT 語句返回數(shù)據(jù),則每個 READTEXT 語句最多可以返回 1 MB (1024 KB) 的數(shù)據(jù)。
  • execute_statement 還可以用于擴展過程。execute_statement 插入由擴展過程的主線程返回的數(shù)據(jù),但不插入主線程以外的線程的輸出。
  • 不能將表值參數(shù)指定為 INSERT EXEC 語句的目標(biāo);但是,可以將它指定為 INSERT EXEC 字符串或存儲過程中的
  • 不能在 INSERT...EXEC 語句中使用 OUTPUT 子句

使用 TOP 限制插入的行

可以使用 TOP 關(guān)鍵字限制插入的行數(shù)。在與 INSERT語句結(jié)合使用的 TOP 表達式中引用的行不按任何順序排列。TOP(n) 隨機返回 n 行。
??例如,下面的 INSERT 語句包含 ORDER BY 子句,但該子句并不影響由 INSERT 語句直接引用的行,INSERT 語句選擇 SELECT 語句返回的任意兩行

INSERT TOP (2) INTO Table2 (ColumnB) 
    SELECT ColumnA FROM Table1 
    ORDER BY ColumnA;

若要確保插入 SELECT 子查詢返回的前兩行,請按如下所示重寫該查詢。

INSERT INTO Table2 (ColumnB) 
    SELECT TOP (2) ColumnA FROM Table1 
    ORDER BY ColumnA;

INSERT (Transact-SQL)

-- Standard INSERT syntax
[ 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 ] ) [ ,...n ] 
          | derived_table 
          | execute_statement
          | <dml_table_source>
          | DEFAULT VALUES 
        }
    }
}
[; ]

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

<dml_table_source> ::=
    SELECT <select_list>
    FROM ( <dml_statement_with_output_clause> ) 
      [AS] table_alias [ ( column_alias [ ,...n ] ) ]
    [ WHERE <search_condition> ]
        [ OPTION ( <query_hint> [ ,...n ] ) ]
  • TOP (expression) [ PERCENT ]
    指定將插入的隨機行的數(shù)目或百分比。expression 可以是行數(shù)或行的百分比。
  • INTO:一個可選的關(guān)鍵字,可以將它用在 INSERT 和目標(biāo)表之間。
  • server_name:表或視圖所在的鏈接服務(wù)器的名稱。
  • database_name:數(shù)據(jù)庫的名稱。
  • schema_name:該表或視圖所屬架構(gòu)的名稱。
  • table_or view_name:要接收數(shù)據(jù)的表或視圖的名稱。表變量在其作用域內(nèi)可用作 INSERT 語句中的表源。
  • OUTPUT 子句:將插入行作為插入操作的一部分返回。結(jié)果可返回到處理應(yīng)用程序或插入到表或表變量中以供進一步處理。
    ??引用本地分區(qū)視圖、分布式分區(qū)視圖或遠程表的 DML 語句或包含 execute_statement 的 INSERT 語句都不支持OUTPUT 子句。在包含 <dml_table_source> 子句的 INSERT 語句中不支持 OUTPUT INTO 子句。
  • VALUES
    引入要插入的數(shù)據(jù)值的一個或多個列表。對于 column_list(如果已指定)或表中的每個列,都必須有一個數(shù)據(jù)值。必須用圓括號將值列表括起來。
  • DEFAULT
    強制數(shù)據(jù)庫引擎加載為列定義的默認值。如果某列并不存在默認值,并且該列允許 Null 值,則插入 NULL。對于使用 timestamp 數(shù)據(jù)類型定義的列,插入下一個時間戳值。DEFAULT 對標(biāo)識列無效。
  • expression:一個常量、變量或表達式。表達式不能包含 EXECUTE 語句。
  • <dml_table_source>
    ??指定插入目標(biāo)表的行是 INSERT、UPDATE、DELETE 或 MERGE 語句的OUTPUT 子句返回的行(和上面的<OUTPUT Clause>沒啥關(guān)系,這里是使用DML產(chǎn)生所要插入目標(biāo)表的行,它們是使用OUTPUT返回的)
    ??如果指定了 <dml_table_source>,外部 INSERT 語句的目標(biāo)必須滿足以下限制:
  • 必須是基表而不是視圖。
  • 不能是遠程表。
  • 不能對其定義任何觸發(fā)器。
  • 不能參與任何主鍵-外鍵關(guān)系。
  • 不能參與合并復(fù)制或事務(wù)復(fù)制的可更新訂閱。
  • <select_list>
    指定要插入 OUTPUT 子句所返回的列的逗號分隔列表。<select_list> 中的列必須與要插入值的列兼容。<select_list> 無法引用聚合函數(shù)或 TEXTPTR。
  • <dml_statement_with_output_clause>
    ??在 OUTPUT 子句中返回受影響行的有效 INSERT、UPDATE、DELETE 或 MERGE 語句(和上面的<OUTPUT Clause>沒啥關(guān)系,這是產(chǎn)生data_table_source的DML語句)
    ??語句中不能包含 WITH 子句,且不能以遠程表或分區(qū)視圖為目標(biāo)。如果指定了 UPDATE 或 DELETE,則所指定的 UPDATE 或 DELETE 不能是基于游標(biāo)的。源行不能作為嵌套的 DML 語句進行引用。
  • WHERE <search_condition>
    任意 WHERE 子句,其中包含對 <dml_statement_with_output_clause> 返回的行進行篩選的有效 <search_condition>

【示例】

A. 將 OUTPUT INTO 用于簡單 INSERT 語句
??下例向 ScrapReason 表插入一行,并使用 OUTPUT 子句將語句的結(jié)果返回給@MyTableVartable變量。由于 ScrapReasonID 列使用 IDENTITY 屬性定義,因此未在 INSERT 語句中為該列指定一個值。但請注意,將在列inserted.ScrapReasonID內(nèi)的 OUTPUT 子句中返回由數(shù)據(jù)庫引擎為該列生成的值。

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID 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 NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate FROM Production.ScrapReason;
GO

**B、使用<dml_table_source>進行插入 **

CREATE TABLE table1  
(  
    id INT,  
    employee VARCHAR(32)  
);  
CREATE TABLE table2
(  
    id INT,  
    person VARCHAR(32)  
);  

INSERT INTO table1 
SELECT a.id,a.person FROM (
   INSERT table2 
     OUTPUT INSERTED.id,INSERTED.person
   VALUES(1,'Ada')
) AS a
GO
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內(nèi)容