2012-03-02 26 views
17

Điều này có vẻ tương đối đơn giản, nhưng rõ ràng là không.TSQL chọn bảng Nhiệt độ từ sql động

tôi cần phải tạo ra một bảng tạm thời dựa trên một bảng hiện có thông qua các lựa chọn vào cú pháp:

SELECT * INTO #TEMPTABLE FROM EXISTING_TABLE 

Vấn đề là, tên bảng hiện có được chấp nhận thông qua một tham số ...

tôi có thể lấy dữ liệu của bảng thông qua:

execute ('SELECT * FROM ' + @tableName) 

nhưng làm cách nào để kết hôn với hai để tôi có thể đưa kết quả từ thực thi trực tiếp vào bảng tạm thời.

Các cột cho mỗi bảng mà điều này sẽ được sử dụng cho không giống nhau để xây dựng bảng tạm thời trước khi nhận dữ liệu không thực tế.

Tôi đang mở cho bất kỳ đề xuất nào ngoại trừ việc sử dụng bảng tạm thời toàn cầu.

Cập nhật:

này là hoàn toàn vô lý, NHƯNG đặt phòng của tôi với các bảng tạm thời toàn cầu là điều này là một nền tảng người dùng đa vay chính nó để vấn đề nếu bảng sẽ kéo dài trong một thời gian dài ...

Sooo .. chỉ để vượt qua phần này tôi đã bắt đầu bằng cách sử dụng lệnh thi hành để tạo bảng tạm thời toàn cầu.

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

sau đó tôi sử dụng bảng tạm thời toàn cầu để tải bảng temp địa phương:

select * into #tempTable from ##globalDynamicFormTable 

sau đó tôi thả các bảng toàn cầu.

drop table ##globalDynamicFormTable 

điều này là bẩn và tôi không thích nó, nhưng hiện tại, cho đến khi tôi có giải pháp tốt hơn, nó sẽ phải hoạt động.

In the End:

Tôi đoán không có cách nào để có được xung quanh nó.

Câu trả lời hay nhất dường như là một trong hai;

Tạo xem trong lệnh thực thi và sử dụng lệnh đó để tải bảng tạm thời cục bộ trong quy trình được lưu trữ.

Tạo bảng tạm thời toàn cầu trong lệnh thi hành và sử dụng để tải bảng tạm thời cục bộ.

Với điều đó nói rằng tôi có lẽ sẽ chỉ gắn bó với bảng tạm thời toàn cầu vì việc tạo và giảm lượt xem được kiểm tra trong tổ chức của tôi và tôi chắc chắn rằng họ sẽ đặt câu hỏi rằng nếu nó bắt đầu xảy ra mọi lúc.

Cảm ơn!

+0

Bạn đang sử dụng phiên bản SQL Server nào? –

+0

sql server 2005 – Patrick

Trả lời

19

Một ví dụ làm việc.

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

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

giải pháp thứ hai với bảng temp truy cập

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

CHỌN thứ hai sau INSERT là cho thấy rằng bạn có thể truy vấn dữ liệu vừa được chèn vào bảng #TEMP. – Kaf

+1

nhưng tạo bảng tạm thời trong thực thi đặt bảng tạm thời hoàn toàn nằm ngoài phạm vi ... hãy thử chọn từ bảng tạm thời bên ngoài lệnh thi hành ... nó sẽ không hoạt động. – Patrick

+0

khai báo vartablename là varchar (100) chọn vartablename = 'tài sản thế chấp' thực hiện ('chọn * thành #temp từ' + vartablename) chọn * từ #temp results in - Tên đối tượng không hợp lệ '#temp'. – Patrick

0

Hãy xem OPENROWSET, và làm điều gì đó như:

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

có các vấn đề về pemissions giữ cho các hàng rào mở hoạt động, chưa kể rằng với 3 môi trường khác nhau, id phải đảm bảo rằng mọi giải pháp này được triển khai bằng cách sử dụng đúng chuỗi kết nối cho openrowset. – Patrick

+2

Điều này không hoạt động - bạn không thể chuyển các biến cho OpenRowset – sianabanana

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

điều này có hoạt động không? –

+2

không, kiểm tra SQL Server 2008 R2 và nó * không * làm việc. –

+0

Đã xảy ra lỗi (cần dấu ngoặc đơn quanh @sql) và không tạo bảng mẫu để chọn, nhưng cách tiếp cận chung trong thực tế hoạt động. Tôi đã sửa những vấn đề này. – chorbs

0

Làm thế nào tôi đã làm nó với một trục trong sql động (#AccPurch đã được tạo ra trước đây)

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

tôi có thể nghĩ ra một vài cách để chọn dữ liệu từ một bảng có tên được tạo động, mà không sử dụng bảng tạm thời toàn cầu.

Giải pháp 1

Xây dựng chuỗi chứa tên của bảng nguồn của bạn, và làm cho toàn bộ truy vấn của bạn năng động.

Giải pháp 2

Giải pháp này, liên quan đến một biến bảng, sẽ làm việc, miễn là bạn biết ...

  • ... số lượng, tên và loại của các cột. ..
  • ... tên của cột khóa chính EDIT: (ok, rõ ràng đây không phải là đúng sự thật, như it can be generated dynamically) ...

trong bảng nguồn của bạn.

-- 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; 

trực giác của tôi nói rằng điều này là có khả năng chậm trên tập hợp dữ liệu lớn, và tôi không biết nếu bạn có thể làm cho động truy vấn này (chúng ta có thể bằng cách truy vấn danh sách các tên cột, using dirty hacks to build the string that contains the list of columns, vv, nhưng bây giờ tôi không thể dành nhiều thời gian hơn cho việc này ...), cho phép bạn chọn dữ liệu từ một bảng với bất kỳ số lượng cột nào; nhưng một lần nữa, đây là SQL ...

Các vấn đề liên quan