插入資料
Transact-SQL 提供多種方式來將資料列插入資料表中。
INSERT 陳述式
INSERT 陳述式可用來將一或多個資料列新增至資料表。 此陳述式有幾種格式。
簡單 INSERT 陳述式的基本語法如下所示:
INSERT [INTO] <Table> [(column_list)]
VALUES ([ColumnName or an expression or DEFAULT or NULL],…n)
您可以使用這種格式的 INSERT 陳述式 (稱為 INSERT VALUES),指定要在其中放入值的資料行,以及插入資料表中的每個資料列顯示資料的順序。 column_list 是選用項目,但建議使用。 如果沒有 column_list,INSERT 陳述式會預期資料表中的每個資料行都有一個值,並以定義資料行時的順序顯示。 您也可以使用逗點分隔清單提供這些資料行的值。
列出值時,關鍵字 DEFAULT 表示將會使用建立資料表時所指定的預先定義值。 有三種方式可以決定預設值:
- 如果資料行已定義為具有自動產生的值,則會使用該值。 本課程模組稍後將會討論自動產生的值。
- 建立資料表時,可為資料行提供預設值;如果指定了 DEFAULT,則會使用該值。
- 如果資料行已定義為允許 NULL 值,而且該資料行不是自動產生的資料行,亦未定義預設值,則會插入 NULL 作為 DEFAULT。
建立資料表的詳細過程不在本課程模組的討論範圍內。 不過,查看資料表中有哪些資料行通常會很有用。 最簡單的方式是直接在資料表上執行 SELECT 陳述式,而不傳回任何資料列。 若使用永遠不可能是 TRUE 的 WHERE 條件,則不會傳回任何資料列。
SELECT * FROM Sales.Promotion
WHERE 1 = 0;
此陳述式會顯示所有資料行及其名稱,但不會顯示資料類型或任何屬性,例如是否允許 NULL,或是否有指定的預設值。 查詢輸出的範例可能如下所示:
PromotionName
StartDate
ProductModelID
折扣
備註
若要將資料插入此資料表中,您可以使用 INSERT 陳述式,如下所示。
INSERT INTO Sales.Promotion (PromotionName,StartDate,ProductModelID,Discount,Notes)
VALUES
('Clearance Sale', '01/01/2021', 23, 0.1, '10% discount');
在上述範例中,您可以省略資料行清單,因為我們會以正確的順序為每個資料行提供一個值:
INSERT INTO Sales.Promotion
VALUES
('Clearance Sale', '01/01/2021', 23, 0.1, '10% discount');
假設資料表已定義為將目前日期的預設值套用至 [開始日期] 資料行,而且 [附註] 資料行允許 NULL 值。 您可以指定要明確使用這些值,如下所示:
INSERT INTO Sales.Promotion
VALUES
('Pull your socks up', DEFAULT, 24, 0.25, NULL);
或者,您可以省略 INSERT 陳述式中的值,在此情況下,系統會使用預設值 (如已定義);如果沒有預設值,但資料行允許 NULL,則會插入 NULL。 如果您未提供所有資料行的值,則必須使用資料行清單指出您所提供的資料行值。
INSERT INTO Sales.Promotion (PromotionName, ProductModelID, Discount)
VALUES
('Caps Locked', 2, 0.2);
除了一次插入一個資料列之外,還可以使用 INSERT VALUES 陳述式,透過提供多個逗點分隔值集插入多個資料列。 這些值集也會以逗號分隔,如下所示:
(col1_val,col2_val,col3_val),
(col1_val,col2_val,col3_val)
此值清單稱為資料表值建構函式。 以下示範如何使用資料表值建構函式,將兩個以上的資料列插入資料表中:
INSERT INTO Sales.Promotion
VALUES
('The gloves are off!', DEFAULT, 3, 0.25, NULL),
('The gloves are off!', DEFAULT, 4, 0.25, NULL);
INSERT ... SELECT
除了在 INSERT 陳述式中指定值的常值集之外,T-SQL 還支援使用其他作業的結果為 INSERT 提供值。 您可以使用 SELECT 陳述式其結果或預存程序的輸出,為 INSERT 陳述式提供值。
若要搭配巢狀 SELECT 使用 INSERT,請建立 SELECT 陳述式以取代 VALUES 子句。 您可以使用這種格式 (稱為 INSERT SELECT),將 SELECT 查詢所傳回的一組資料列插入目的地資料表中。 使用 INSERT SELECT 與 INSERT VALUES 有相同的考量:
- 您可以選擇性地在資料表名稱之後指定資料行清單。
- 您必須為每個資料行提供資料行值或 DEFAULT,或是 NULL。
下列語法說明 INSERT SELECT 的用法:
INSERT [INTO] <table or view> [(column_list)]
SELECT <column_list> FROM <table_list>...;
注意
預存程序 (或甚至動態批次) 其結果集也可以作為 INSERT 陳述式的輸入。 這種格式的 INSERT (稱為 INSERT EXEC) 在概念上與 INSERT SELECT 很類似,而且會有相同的考量。 不過,預存程序可能會傳回多個結果集,因此需要格外小心。
下列範例會從 Production.ProductModel 資料表中擷取名稱包含 "frame" 的每個模型其模型識別碼和模型名稱,針對名為 Get Framed 的新促銷插入多個資料列。
INSERT INTO Sales.Promotion (PromotionName, ProductModelID, Discount, Notes)
SELECT DISTINCT 'Get Framed', m.ProductModelID, 0.1, '10% off ' + m.Name
FROM Production.ProductModel AS m
WHERE m.Name LIKE '%frame%';
與子查詢不同的是,搭配 INSERT 使用的巢狀 SELECT 不會以括弧括住。
SELECT ... INTO
插入資料列的另一個選項是 SELECT INTO 陳述式,其與 INSERT SELECT 很類似。 INSERT SELECT 與 SELECT INTO 之間的最大差異,在於無法使用 SELECT INTO 將資料列插入現有資料表中,因為其一律會根據 SELECT 的結果建立新資料表。 新資料表中每個資料行的名稱、資料類型和 Null 屬性都會與 SELECT 清單中的對應資料行 (或運算式) 相同。
若要使用 SELECT INTO,請在查詢的 SELECT 子句中新增 INTO <new_table_name> (緊接在 FROM 子句之前)。 以下示範如何將 Sales.SalesOrderHeader 資料表中資料擷取到名為 Sales.Invoice 的新資料表中。
SELECT SalesOrderID, CustomerID, OrderDate, PurchaseOrderNumber, TotalDue
INTO Sales.Invoice
FROM Sales.SalesOrderHeader;
如果在 INTO 之後已有指定名稱的資料表,則 SELECT INTO 將會失敗。 建立資料表之後,即可像任何其他資料表一樣進行處理。 您可以從資料表中選取資料、將其聯結至其他資料表,或在其中插入更多資料列。