2010-10-01 56 views
271

得到一個複雜的SELECT查詢,我想從中插入所有行到表變量中,但T-SQL不允許它。SELECT INTO T-SQL中的表變量

沿着同樣的路線,您不能在SELECT INTO或INSERT EXEC查詢中使用表變量。 http://odetocode.com/Articles/365.aspx

短例如:

declare @userData TABLE(
         name varchar(30) NOT NULL, 
         oldlocation varchar(30) NOT NULL 
         ) 

SELECT name, location 
INTO @userData 
FROM myTable 
    INNER JOIN otherTable ON ... 
WHERE age > 30 

在表變量的數據將在以後用於插入/更新它放回不同的表(主要與次要更新相同數據的複製)。這樣做的目標是簡單地使腳本更易讀,更容易定製,而不是直接將SELECT INTO放入正確的表格中。 性能不是問題,因爲rowcount相當小,只有在需要時才手動運行。
...或者只是告訴我,如果我做錯了。

回答

423

嘗試是這樣的:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL, 
    oldlocation varchar(30) NOT NULL 
); 

INSERT INTO @userData (name, oldlocation) 
SELECT name, location FROM myTable 
INNER JOIN otherTable ON ... 
WHERE age > 30; 
+0

如果您將「SELECT name,location FROM myTable」作爲將要插入到UserData表中的值,則select中變量的名稱是否與表定義中的名稱匹配無關緊要。你選擇'name'進入UserData'name'變量,但是你選擇'location'並以某種方式將它分配給UserData'oldlocation'變量。 SQL會自動映射它們還是會拋出某種異常? – 2015-11-17 07:23:38

+0

名稱無關緊要,只有列類型。 – CristiC 2015-11-18 04:26:35

+3

哇,這是有道理的,但在同一時間在我的語法分析器感到有點冒犯:) – 2015-11-18 04:28:14

6

嘗試使用INSERT而不是SELECT INTO

INSERT @UserData 
SELECT name, location etc. 
12

你可以嘗試使用臨時表...

SELECT name, location INTO #userData FROM myTable 
INNER JOIN otherTable ON ... 
WHERE age>30 

你跳過申報表這樣的努力... 幫助對於adhoc查詢......這將創建一個本地臨時表,除非您在應用程序中使用相同的連接,否則其他連接將不可見。

,如果你需要的變量,可以這樣聲明:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL, 
    oldlocation varchar(30) NOT NULL 
); 

INSERT INTO @userData 
SELECT name, location FROM myTable 
INNER JOIN otherTable ON ... 
WHERE age > 30; 
+2

對不起,忘了提及我沒有CREATE TABLE的權利。 – Indrek 2010-10-01 10:23:23

+6

創建臨時存在更多的開銷。使用臨時表的 – Paparazzi 2012-12-04 17:07:43

+2

並不總是安全的。例如,Web服務。通過單一連接的webservices來限制服務器上的最大連接和保護SQL一點點,臨時表將存在每個查詢通過,並可以覆蓋當前使用它的人。 – Franck 2014-03-05 13:43:56

77

SELECT INTO目的是(根據文檔,我的重點)

創建從另一個表中的值中創建一個新表

但是你已經一個目標表!所以,你想要的是

INSERT語句添加一個或多個新行到表

您可以在 以下方法指定數據值:

...

通過使用SELECT子查詢,以指定 的數據值用於一個或更多的行, 如:

INSERT INTO MyTable 
(PriKey, Description) 
     SELECT ForeignKey, Description 
     FROM SomeView 

而在語法,它允許MyTable是一個表變量。使用SELECT INTO

+0

感謝您的解釋! – Indrek 2010-10-01 10:33:32

+0

真的希望接受的答案包括這個信息! – 2015-09-16 12:45:24

+0

我得到的MyTable是「無效的對象名稱」這樣做,所以這個答案有一些缺失。 – 2017-08-11 13:45:13

-4

的一個原因是,它允許您使用的身份:

SELECT IDENTITY(INT,1,1) AS Id, name 
INTO #MyTable 
FROM (SELECT name FROM AnotherTable) AS t 

這不是一個表變量,這是太糟糕工作...

+5

儘管您可以聲明一個具有「IDENTITY」列的表變量。 – 2013-10-20 18:57:17

4

首先創建一個臨時表:

步驟1:

create table #tblOm_Temp (

    Name varchar(100), 
    Age Int , 
    RollNumber bigint 
) 

**步驟2:**在Temp表格中插入一些值。

insert into #tblom_temp values('Om Pandey',102,1347) 

步驟3:聲明一個表變量來保存臨時表的數據。

declare @tblOm_Variable table(

    Name Varchar(100), 
    Age int, 
    RollNumber bigint 
) 

步驟4:從臨時表選擇值,並插入到表變量。

insert into @tblOm_Variable select * from #tblom_temp 

最後值從臨時表插入到表可變

步驟5:可以檢查在表變量插入的值。

select * from @tblOm_Variable 
13

您還可以使用公用表表達式來存儲臨時數據集。他們更優雅,即興友好:

WITH userData (name, oldlocation) 
AS 
(
    SELECT name, location 
    FROM myTable INNER JOIN 
     otherTable ON ... 
    WHERE age>30 
) 
SELECT * 
FROM userData -- you can also reuse the recordset in subqueries and joins 
+0

喜歡這個!謝謝。 – fourpastmidnight 2018-02-02 21:12:43

0

OK,現在有了足夠的努力,我能夠插入@table使用如下:

INSERT @TempWithheldTable SELECT
a.SuspendedReason, a.SuspendedNotes, a.SuspendedBy, a.ReasonCode FROM OPENROWSET(BULK 'C:\ databases中\ WithHeld.csv',FORMATFILE = N'C:\ databases中\ Format.txt」,
錯誤文件= N'C :\特mp \ MovieLensRatings.txt' )AS a;

這裏最主要的是選擇要插入的列。