2011-07-29 16 views
6

Powiedzmy mam zapytanie tak:Czy istnieje sposób na określenie nazwy tabeli jako łańcucha znaków?

SELECT * FROM 
(
    SELECT * FROM 
    (
    SELECT * FROM DB.dbo.Table 
) 
    INNER JOIN DB.dbo.Table ON ... 

Używam tego zapytania wielokrotnie z różnych tabel ręcznie zmienić ciąg wszędzie. Próbowałem deklarowania następujące:

DECLARE @tablename AS VARCHAR(255) 
SET @tablename = 'DB.dbo.Table' 

Ale to nie wydają się działać jak rzuca mi błąd mówiąc, że muszę zadeklarować jako zmienną @tablename tabeli przed mogę go używać. Jak mogę zmienić nazwę mojej tabeli, a jeśli to możliwe, czy IntelliSense nadal działa?

Odpowiedz

7

Można owinąć go w exec tak:

declare @my_tablename nvarchar(100) = 'mytable'; 
exec(' 
SELECT * FROM 
(
    SELECT * FROM 
    (
    SELECT * FROM ' + @my_tablename + ' 
) 
    INNER JOIN ' + @my_tablename + ' ON ...' 
); 

Ale nie, intellisense nie działa w tym scenariuszu.

Jeśli wiesz, jak będą wyglądać wydruki z wyprzedzeniem, możesz zadeklarować tabelę tymczasową, w której będą przechowywane wyniki, a następnie możesz uzyskać do niej dostęp bez EXEC. Będziesz miał intellisense na stole tymczasowym.

Na przykład:

--this must match whatever your SELECT is going to return 
    CREATE TABLE #results(
    FIELD1 INT 
    ,FIELD2 NVARCHAR(100) 
    ,FIELD3 BIT 
    ); 

EXEC(' 
    INSERT INTO #results(field1,field2,field3) 
    SELECT FIELD1,FIELD2,FIELD3 FROM ' + @my_tablename 
); 

select * from #results --you will have intellisense on #results 
3

użyć dynamicznego SQL. Nie wiesz, dlaczego potrzebujesz wielu zagnieżdżonych SELECT, ale będzie to coś w rodzaju:

DECLARE @sql NVARCHAR(MAX) = N'SELECT ... FROM ' + @tablename + '...'; 
EXEC sp_executeSQL @sql; 

Pamiętaj jednak o wstrzyknięciu SQL. I nie, IntelliSense nie ma możliwości analizowania ciągu znaków dla nazw obiektów (lub nawet wiedzieć podczas edycji, jaka nazwa obiektu będzie tam obecna).

+0

+1. Dziękuję za wzmiankę o wstrzyknięciu zależności. –

4

Nie. Tak jak nie można podać nazwy funkcji w programie C# jako łańcucha znaków. Kompilacja T-SQL ma wymyślić dokładny plan dostępu, czyli jakie indeksy otworzyć i użyć, aby spełnić zapytanie. Byłoby niemożliwe, aby wymyślić plan na "ciąg", tak jak byłoby to niemożliwe w C#, aby wygenerować kod, aby wywołać "ciąg" jako metodę.

Rozwiązaniem jest dynamiczny SQL:

declare @sql NVARCHAR(MAX) = N'SELECT ... FROM ' + 
    quotename(@dbname) + N'.' + quotename(@schema) + N'.' + quotename(@table) + 
    N' WHERE ...'; 
exec sp_executesql @sql; 

... tak jak w C# byłoby użyć refleksji zrobić dynamiczną wykonania inwokację.

Aby uzyskać więcej informacji, patrz The Curse and Blessings of Dynamic SQL.

PS. podział @tablename na komponenty i użycie QUOTENAME jest absolutną koniecznością, chroni agaisnt SQL Injection. Użyj PARSENAME, aby zrobić podział dla ciebie.

+0

+1 dla łącza, zawsze jest to pierwsze miejsce, gdy mamy do czynienia z dynamicznym SQL – Lamak

Powiązane problemy