2012-03-02 87 views
17

這看起來相對簡單,但顯然不是。TSQL從動態sql中選擇到Temp表中

我需要通過選擇創建基於現有的表的臨時表到語法:

SELECT * INTO #TEMPTABLE FROM EXISTING_TABLE 

問題是,現有的表名是通過參數接受...

我可以通過獲取表的數據:

execute ('SELECT * FROM ' + @tableName) 

,但我怎麼娶兩個,這樣我就可以把從直接執行結果到臨時表。

這將用於每個表的列是不相同的,因此在獲取數據之前構建臨時表是不實際的。

我打開任何建議,除了使用全局臨時表。

更新:

這完全是荒謬的,但我與全局臨時表保留的是,這是一個多用戶平臺適合於問題,如果該表將徘徊很長一段時間...

Sooo ..只是爲了克服這部分,我已經開始使用execute來生成全局臨時表。

execute('select * into ##globalDynamicFormTable from ' + @tsFormTable) 

然後我用全局臨時表來加載本地臨時表:

select * into #tempTable from ##globalDynamicFormTable 

我然後刪除全局表。

drop table ##globalDynamicFormTable 

這是骯髒的,我不喜歡它,但暫時,直到我得到一個更好的解決方案,它將不得不工作。

中底:

我想有沒有辦法繞過它。

最好的答案似乎是或者;

在執行命令中創建一個視圖並使用它在存儲過程中加載本地臨時表。

在執行命令中創建一個全局臨時表並使用它來加載本地臨時表。

這樣說我可能會堅持使用全局臨時表,因爲創建和刪除視圖在我的組織中進行了審計,並且我相信他們會質疑,如果它始終發生。

謝謝!

+0

你在什麼版本的SQL Server? – 2012-03-02 15:39:24

+0

sql server 2005 – Patrick 2012-03-02 15:58:26

回答

19

的工作示例。

DECLARE @TableName AS VARCHAR(100) 
SELECT @TableName = 'YourTableName' 

EXECUTE ('SELECT * INTO #TEMP FROM ' + @TableName +'; SELECT * FROM #TEMP;') 

配有殘疾人專用臨時表二的解決方案

DECLARE @TableName AS VARCHAR(100) 
SELECT @TableName = 'YOUR_TABLE_NAME' 

EXECUTE ('CREATE VIEW vTemp AS 
     SELECT * 
     FROM ' + @TableName) 
SELECT * INTO #TEMP FROM vTemp 

--DROP THE VIEW HERE  
DROP VIEW vTemp 

/*START USING TEMP TABLE 
************************/ 
--EX: 
SELECT * FROM #TEMP 


--DROP YOUR TEMP TABLE HERE 
DROP TABLE #TEMP 
+0

INSERT後的第二個SELECT表明你可以查詢剛剛插入到#TEMP表中的數據。 – Kaf 2012-03-02 15:13:54

+1

,但在執行中創建臨時表會將臨時表完全超出範圍......嘗試從執行命令之外的臨時表中進行選擇......它將無法工作。 – Patrick 2012-03-02 15:17:42

+0

declare vartablename as varchar(100) select vartablename ='collat​​eral' execute('select * into #temp from'+ vartablename) select * from #temp result - 無效的對象名'#temp'。 – Patrick 2012-03-02 15:19:49

0

看看OPENROWSET,並做一些事情,如:

SELECT * INTO #TEMPTABLE FROM OPENROWSET('SQLNCLI' 
    , 'Server=(local)\SQL2008;Trusted_Connection=yes;', 
    'SELECT * FROM ' + @tableName) 
+0

有些權限問題會導致打開的行集無法工作,更不用說在3種不同的環境下,id必須確保每次部署此解決方案時,它都使用openrowset的正確連接字符串。 – Patrick 2012-03-02 15:06:40

+2

這不起作用 - 你不能將變量傳遞給OpenRowset – sianabanana 2016-01-06 12:06:43

1
declare @sql varchar(100); 

declare @tablename as varchar(100); 

select @tablename = 'your_table_name'; 

create table #tmp 
    (col1 int, col2 int, col3 int); 

set @sql = 'select aa, bb, cc from ' + @tablename; 

insert into #tmp(col1, col2, col3) exec @sql; 

select * from #tmp; 
+0

做這個甚至工作? – 2013-09-18 21:02:17

+2

nope,選中SQL Server 2008 R2,它*不工作。 – 2013-09-18 21:08:51

+0

它有一個錯誤(圍繞@sql需要括號),並沒有創建示例表來選擇,但一般的方法確實有效。我糾正了這些問題。 – chorbs 2016-09-26 05:40:15

0

如何在動態SQL樞軸做到了(#AccPurch在此之前創建的)

DECLARE @sql AS nvarchar(MAX) 
declare @Month Nvarchar(1000) 

--DROP TABLE #temp 
select distinct YYYYMM into #temp from #AccPurch AS ap 
SELECT @Month = COALESCE(@Month, '') + '[' + CAST(YYYYMM AS VarChar(8)) + '],' FROM #temp 

SELECT @Month= LEFT(@Month,len(@Month)-1) 


SET @sql = N'SELECT UserID, '+ @Month + N' into ##final_Donovan_12345 FROM (
Select ap.AccPurch , 
     ap.YYYYMM , 
     ap.UserID , 
     ap.AccountNumber 
FROM #AccPurch AS ap 
) p 
Pivot (SUM(AccPurch) FOR YYYYMM IN ('[email protected]+ N')) as pvt' 


EXEC sp_executesql @sql 

Select * INTO #final From ##final_Donovan_12345 

DROP TABLE ##final_Donovan_12345 

Select * From #final AS f 
0

我可以考慮幾種方法從動態生成名稱的表中選擇數據,而不使用全局臨時表。

解決方案1 ​​

構建包含源表的名稱的字符串,使您的整個動態查詢。

解決方案2

該解決方案,涉及表變量,將工作,前提是你知道...

在您的源表中。

-- Number of rows in your source table 
DECLARE @RowCount INT; 
SELECT @RowCount = SUM(st.row_count) FROM sys.dm_db_partition_stats st WHERE object_name(object_id) = EmployeesWeek_ + CONVERT(VARCHAR(10),WEEK(GETDATE())) AND (index_id < 2); 

-- All columns from your source table 
DECLARE @col1 int; 
DECLARE @col2 varchar(50); 
DECLARE @col3 varchar(5); 
DECLARE @col4 int; 
DECLARE @col5 smalldatetime; 
DECLARE @col6 bit; 

-- This table variable will store the data 
DECLARE @Dump TABLE (
    col1 int, 
    col2 varchar(50), 
    col3 varchar(5), 
    col4 int, 
    col5 smalldatetime, 
    col6 bit 
) 

DECLARE @RowIter INT = 1; 
WHILE @RowIter <= @RowCount 
BEGIN 
    DECLARE @QueryString NVARCHAR(MAX) = CONCAT(N' 
      SELECT 
       @col1 = ID, 
       @col2 = Name, 
       @col3 = NameAbbr, 
       @col4 = UpdatedBy, 
       @col5 = DateUpdated, 
       @col6 = Active 

      FROM (
       SELECT 
        ROW_NUMBER() OVER (ORDER BY PKArea ASC) AS RowNum, 
        * 
       FROM 
        EmployeesWeek_',WEEK(GETDATE()),' 
      ) sq 

      WHERE 
       RowNum = ', @RowIter , ' 
      ; 
     '); 
    EXEC dbo.sp_executesql 
     @QueryString, 
     -- OUTPUT VARIABLE DECLARATION 
     N' 
      @col1 int out, 
      @col2 varchar(50) out, 
      @col3 varchar(5) out, 
      @col4 int out, 
      @col5 smalldatetime out, 
      @col6 bit out 
     ', 
     -- ALL OUTPUT VARIABLES 
     @col1 out, 
     @col2 out, 
     @col3 out, 
     @col4 out, 
     @col5 out, 
     @col6 out 
    ; 

    INSERT INTO @Dump values(@col1, @col2, @col3, @col4, @col5, @col6); 

    SET @RowIter = @RowIter + 1; 

END 

SELECT * FROM @Dump; 

我的直覺說,這是對大數據集可能慢,我不知道是否可以讓這個動態查詢(它應該通過查詢列名,using dirty hacks to build the string that contains the list of columns等的列表是可能的,但現在我不能再花這麼多時間......),使您能夠從任意列數的表中選擇數據;但再一次,這是SQL ...