2009-08-24 4 views
11

Chcę napisać przechowywany proc, który użyje parametru, który będzie nazwą tabeli.Dynamiczny SQL (przekazywanie nazwy tabeli jako parametru)

Np:

@tablename << Parameter 

SELECT * FROM @tablename 

Jak to możliwe?

pisałem tak:

set ANSI_NULLS ON 
set QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[GetAllInterviewQuestions] 
@Alias varchar = null 
AS 
BEGIN 
Exec('Select * FROM Table as ' @Alias) 
END 

ale mówi Niepoprawna składnia w pobliżu @Alias.

Odpowiedz

18

Po pierwsze, pominięto znak "+" ze stringa. Taki sposób robienia rzeczy jest daleki od ideału, ale można to zrobić

DECLARE @SQL varchar(250) 
SELECT @SQL = 'SELECT * FROM ' + QuoteName(@Alias) 
Exec(@SQL) 

bym zdecydowanie wskazują na przemyślenia, jak to zrobić, jednak. Generowanie dynamicznego SQL często prowadzi do luk w SQL Injection, a także do utrudniania SQL Server (i innym bazom danych) wypracowania najlepszego sposobu na przetworzenie zapytania. Jeśli masz procedurę przechowywaną, która może zwrócić tabelę, naprawdę nie zyskujesz praktycznie żadnej korzyści z tego, że jest to procedura składowana, ponieważ nie będzie ona w stanie zrobić wiele w zakresie optymalizacji. w dużym stopniu również wyłudzające korzyści związane z bezpieczeństwem.

1

Często konieczność sparametryzowania nazwy tabeli oznacza, że ​​należy ponownie przemyśleć schemat bazy danych. Jeśli przesyłasz pytania do rozmowy kwalifikacyjnej z wielu różnych tabel, prawdopodobnie lepiej jest utworzyć jedną tabelę z kolumną rozróżniającą pytania, niezależnie od tego, jakie byłyby różne tabele.

0

Większość implementacji SQL nie pozwala na określenie elementów strukturalnych - nazw tabel, nazw kolumn, kolejności według kolumn itd. - za pomocą parametrów; musisz użyć dynamicznego SQL do sparametryzowania tych aspektów zapytania.

Jednak patrząc na SQL, trzeba:

Exec('SELECT * FROM Table AS ' @Alias) 

pewnością oznaczałoby to, że kod będzie zawsze tylko wybrać z tabeli o nazwie „Tabela”, a trzeba by złączyć @Alias z nim - iw wielu SQL dialektów, powiązanie jest wskazany przez „||”:

Exec('SELECT * FROM Table AS ' || @Alias) 

to jeszcze prawdopodobnie nie robić co chcesz - ale może nie generować błąd składni, gdy procedura jest tworzony (ale prawdopodobnie wygeneruje błąd w czasie wykonywania).

4

Musisz zrobić to tak: exec('select * from '[email protected]+' where...')

Ale upewnij się, że w pełni zrozumieć zagrożenia, takie jak ataki SQL injection. Ogólnie rzecz biorąc, nie powinieneś nigdy używać czegoś takiego, jeśli DB jest dobrze zaprojektowany.

+2

Lepiej jest zawijać nazwę tabeli w nawiasach kwadratowych, aby zabezpieczyć się przed nazwami tabel, które są zarezerwowanymi słowami i/lub zawierają spacje w nazwie tabeli. exec ('wybierz * od [' + @ tablename + '] gdzie ...') –

3

Nie znaczy

Exec('SELECT * FROM ' + @tableName) 

Również błędu masz jest ponieważ zapomniałeś o + przed @Alias.