2012-03-02 14 views
17

Wydaje się to stosunkowo proste, ale najwyraźniej tak nie jest.TSQL wybierz do tabeli Temp z dynamicznego sql

muszę utworzyć tabelę temp na podstawie istniejącej tabeli poprzez select do składni:

SELECT * INTO #TEMPTABLE FROM EXISTING_TABLE 

Problemem jest istniejąca nazwa tabeli jest akceptowana przez parametr ...

I można uzyskać dane tabeli za pośrednictwem:

execute ('SELECT * FROM ' + @tableName) 

ale jak mogę ożenić się z dwóch tak, że mogę umieścić wynikami wykonać bezpośrednio w tabeli temp.

Kolumny dla każdej tabeli, w której będzie to używane, nie są takie same, więc budowanie tabeli tymczasowej przed uzyskaniem danych nie jest możliwe.

Jestem otwarty na wszelkie sugestie oprócz użycia globalnej tabeli tymczasowej.

Aktualizacja:

Jest to całkowicie niedorzeczne, ale moja rezerwacja z globalnej tabeli temp, że jest to platforma multi użytkownik nadaje się do kwestii, czy tabela będzie utrzymywał się przez dłuższy czas ...

Sooo .. aby ominąć tę część, zacząłem od użycia execute do wygenerowania globalnej tabeli temp.

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

Następnie używać globalnej tabeli temp załadować lokalnej tabeli temp:

select * into #tempTable from ##globalDynamicFormTable 

Następnie upuść globalnej tabeli.

drop table ##globalDynamicFormTable 

to jest brudne i nie podoba mi się to, ale na razie, dopóki nie otrzymam lepszego rozwiązania, jego będzie musiało działać.

W końcu:

Chyba nie ma sposobu, aby dostać się wokół niego.

Najlepszą odpowiedzią wydaje się być;

Utwórz polecenie , zobacz w komendzie execute i użyj go do załadowania lokalnej tabeli tymczasowej w procedurze przechowywanej.

Utwórz globalną tabelę tymczasową w komendzie execute i użyj jej do załadowania lokalnej tabeli temp.

Powiedziawszy, prawdopodobnie będę trzymać się globalnej tabeli tymczasowej, ponieważ tworzenie i upuszczanie widoków jest kontrolowane w mojej organizacji, i jestem pewien, że będą kwestionować to, jeśli zacznie się to dziać cały czas.

Dzięki!

+0

Jaką wersję programu SQL Server używasz? –

+0

Serwer sql 2005 – Patrick

Odpowiedz

19

przykład roboczych.

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

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

drugie rozwiązanie ze stołem dostępny 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

Drugie WYBIERANIE po INSERT ma pokazać, że możesz zapytać dane właśnie wstawione do tabeli #TEMP. – Kaf

+1

ale tworzenie tabeli tymczasowej w wykonaniu powoduje, że tabela temp całkowicie wykracza poza zakres ... spróbuj zrobić wybór z tabeli tymczasowej poza poleceniem wykonania ... nie zadziała. – Patrick

+0

zadeklaruj vartablename jako varchar (100) wybierz vartablename = 'collateral' wykonaj ('wybierz * do #temp od' + vartablename) wybierz * z #temp wyników - Nieprawidłowa nazwa obiektu '#temp'. – Patrick

0

Spójrz na OPENROWSET i zrobić coś takiego:

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

są problemy z pemisjami, które powodują, że otwarty zestaw wierszy nie działa, nie wspominając o tym, że w 3 różnych środowiskach id musi upewnić się, że za każdym razem, gdy to rozwiązanie zostanie wdrożone, używa prawidłowego ciągu połączenia dla zestawu openrowset. – Patrick

+2

To nie działa - nie możesz przekazać zmiennych do 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

to działa? –

+2

nope, sprawdzone SQL Server 2008 R2 i * nie działa *. –

+0

Wystąpił błąd (trzeba nawiasy okrągłe wokół @ sqq) i nie utworzono przykładowej tabeli do wyboru, ale ogólne podejście faktycznie działa. Poprawiłem te problemy. – chorbs

0

jak to zrobiłem z pivot w dynamiczny SQL (#AccPurch powstała przed tym)

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

I może wymyślić kilka sposobów wyboru danych z tabeli, której nazwa została wygenerowana dynamicznie, bez użycia globalnych tabel tymczasowych.

Rozwiązanie 1

zbudować ciąg, który zawiera nazwę tabeli źródłowej i uczynić całe zapytanie dynamiczne.

Rozwiązanie 2

To rozwiązanie, obejmujące zmienną stołowego, będzie działać pod warunkiem, że wiesz ...

  • ... numer, nazwę i typ kolumn. ..
  • ... nazwa kolumny klucza podstawowego EDIT (ok, widocznie nie jest to do końca prawdą, ponieważ it can be generated dynamically) ...

w tabeli źródłowej.

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

Moja intuicja mówi, że to potencjalnie powolne na dużych zbiorach danych, a nie wiem, czy można zrobić to dynamikę zapytań (powinno być możliwe poprzez odpytywanie listę nazw kolumn, using dirty hacks to build the string that contains the list of columns itp, ale na razie nie mogę poświęcić więcej czasu na to ...), umożliwiając wybranie danych z tabeli z dowolną liczbą kolumn; ale znowu to jest SQL ...

Powiązane problemy