2012-05-24 13 views
5

Czy jest możliwe przekazanie nazwy tabeli jako parametru wejściowego do procedury składowanej?Nazwa tabeli przechodzącej w procedurze przechowywanej sql

Na przykład:

create procedure test 
@tablename char(10) 
as 
begin 
select * from @tablename 
end 
go 

wiem, że to nie działa. Więc jaki jest najlepszy sposób, jeśli chcę przekazać nazwę tabeli do procedury przechowywanej?

Wielkie dzięki

Odpowiedz

10

Najbezpieczniejszym sposobem zrobienia tego jest widok.

Utwórz widok, z którym połączeniem wszystkie tabele, do których chcesz uzyskać dostęp (i które muszą mieć tę samą strukturę kolumn), i przedrostkiem wiersze z nazwą tabeli.

CREATE VIEW MultiTable 
AS 
    SELECT 'table1' AS TableName, * FROM table1 
    UNION ALL 
    SELECT 'table2' AS TableName, * FROM table2 
    UNION ALL 
    SELECT 'table3' AS TableName, * FROM table3 

procedura składowana może teraz filtrować nazwy tabeli:

CREATE PROCEDURE test 
    @TableName varchar(100) 
AS 
    SELECT * FROM MultiTable WHERE TableName = @TableName 

Jest to bezpieczniejsze niż używanie dynamiczne tworzenie SQL i wykonanie.

+0

Dziękuję bardzo. – gunnerz

+1

Należy zauważyć, że za pomocą "*" przykład zakłada, że ​​wszystkie trzy tabele mają taką samą liczbę kolumn. Uważam, że w przeciwnym razie wystąpiłby błąd. Nawet jeśli tak było, jako najlepszą praktykę powinieneś prawdopodobnie wyliczyć je w każdym SELECT. – Buggieboy

+0

@Buggieboy może uzyskać ten błąd, jeśli kolumny są zmiany tylko w jednej z tabel jest warto ........ –

3

Musisz użyć dynamicznego SQL, ale musisz zdawać sobie sprawę z potencjalnego ryzyka związanego z wtryskiem sql, do którego się otworzysz, tak jakby nazwa_znacznika zawierała coś podejrzanego, możesz skończyć w świecie bólu.

np.

-- basic check to see if a table with this name exists 
IF NOT EXISTS(SELECT * FROM sys.tables WHERE name = @tablename) 
    RETURN 

DECLARE @sql NVARCHAR(100) 
SET @sql = 'SELECT * FROM ' + QUOTENAME(@tablename) 
EXECUTE(@sql) 

Musisz być bardzo ostrożny z tym podejściem, upewnij się, że nie otwierają puszkę Pandory bezpieczeństwa.

Moim innym zmartwieniem jest to, że możesz próbować generować sprocs dostępu do danych, co zwykle jest złym pomysłem. Oczywiście nie znam twojego przypadku użycia.

+1

[Twój jest numer jeden!] (Http://www.sommarskog.se/dynamic_sql. html # Common_cases) – Bridge

+0

Dziękuję bardzo. Istnieje prawie nikła szansa na wtrysk sql, ponieważ nie ma wpisu użytkownika dla nazwy tabeli. Jest używany tylko przez aplikację wewnętrznie - i chcę uniknąć tworzenia wielu przechowywanych prcs z tą samą logiką, z wyjątkiem różnych nazw tabel – gunnerz

+1

@Bridge - tak, zgadzam się w pełni. Przypadki, w których naprawdę potrzebowałem dynamicznej nazwy tabeli, osobiście wygenerowałem kod SQL w kodzie aplikacji. Ale nie jest tak często, że znalazłem prawdziwy przypadek użycia – AdaTheDev

2
DECLARE @Name VARCHAR(50) 
SET @Name='Company' 

EXEC('SELECT * from ' + @Name) 

użyć w ten sposób, aby uzyskać zapis z bazy danych.

Powiązane problemy