2009-08-24 15 views
11

Desidero scrivere un processo memorizzato che utilizzerà un parametro, che sarà il nome della tabella.SQL dinamico (nome tabella di passaggio come parametro)

es:

@tablename << Parameter 

SELECT * FROM @tablename 

Come è possibile?

ho scritto questo:

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 

Ma dice la sintassi non corretta in prossimità @Alias.

risposta

18

Bene, in primo luogo hai omesso il "+" dalla stringa. Questo modo di fare le cose è ben lungi dall'essere ideale, ma si può fare

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

mi piacerebbe consigliamo vivamente ripensare come si esegue questa operazione, tuttavia. Generare Dynamic SQL porta spesso a vulnerabilità di SQL Injection e rende più difficile per SQL Server (e altri DB) elaborare il modo migliore per elaborare la query. Se si dispone di una stored procedure che può restituire qualsiasi tabella, in realtà non si ottiene praticamente alcun beneficio dal fatto che si tratta di una stored procedure in quanto non sarà in grado di fare molto in termini di ottimizzazioni e in gran parte smascherando anche i vantaggi di sicurezza.

1

Spesso, la necessità di parametrizzare il nome della tabella indica che è necessario ripensare lo schema del database. Se si stanno tracciando le domande dell'intervista da più tabelle diverse, è probabilmente meglio creare una tabella con una colonna che distingua tra le domande in qualsiasi modo le diverse tabelle avrebbero.

0

La maggior parte delle implementazioni di SQL non consente di specificare elementi strutturali - nomi di tabelle, nomi di colonne, ordine per colonne, ecc. - tramite parametri; devi usare l'SQL dinamico per parametrizzare quegli aspetti di una query.

Tuttavia, guardando l'SQL, si ha:

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

Sicuramente, questo significherebbe che il codice sarà sempre e solo scegliere tra una tabella chiamata 'Table', e si avrebbe bisogno di concatenare i @Alias con esso - e in molti dialetti SQL, la concatenazione è indicato da '||':

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

Questo ancora probabilmente non fa ciò che si vuole - ma non potrebbe generare un errore di sintassi quando viene creato il procedimento (ma probabilmente genererebbe un errore in fase di esecuzione).

4

Dovrete fare in questo modo: exec('select * from '[email protected]+' where...')

Ma assicuratevi di comprendere appieno i rischi, come attacchi di SQL injection. In generale, non dovresti mai usare qualcosa del genere se il DB è ben progettato.

+2

E 'un po' meglio per avvolgere il nome della tabella tra parentesi quadre per proteggersi da nomi di tabella che sono parole riservate e/o includere spazi nel nome della tabella. exec ('select * from [' + @ tablename + '] where ...') –

3

Non Vuoi dire

Exec('SELECT * FROM ' + @tableName) 

Inoltre, l'errore che si ottiene è perché avete dimenticato un + prima @Alias.

Problemi correlati