È possibile CREATE VIEW con parametri?
-
06-07-2019 - |
Domanda
Ho un database (SQL Server 2005) in cui mi piacerebbe creare viste al volo. Nel mio codice, sto creando un'istruzione CREATE VIEW, ma l'unico modo in cui riesco a farlo funzionare è creando l'intera stringa di query ed eseguendola nuda. Vorrei usare i parametri, ma questo:
SqlCommand cmd = new SqlCommand("CREATE VIEW @name AS SELECT @body");
cmd.Parameters.AddWithValue("@name", "foo");
cmd.Parameters.AddWithValue("@body", "* from bar");
mi dice che c'è un errore " vicino alla parola chiave VIEW " (presumibilmente il " @ name ") - inutile dire " CREATE VIEW foo AS SELECT * FROM bar "
funziona come un campione.
Non è possibile? In caso contrario, esiste un modo migliore per ripulire l'input prima di eseguire l'istruzione CREATE? In alcuni casi, il corpo della query potrebbe avere l'input dell'utente e mi sentirei più sicuro se potessi dire "trattalo come il corpo di una singola istruzione select". Forse quello che sto chiedendo è troppo strano?
FOLLOWUP 04 nov: OK, sì, quello che voglio è un po 'come l'iniezione SQL quando si arriva ad esso, ma vorrei almeno minimizzare (se non rimuovere totalmente) l'opzione di eseguire questo comando e far cadere una tabella o qualcosa del genere. Concesso, l'utente questo è in esecuzione in quanto non dispone delle autorizzazioni per eliminare qualsiasi tabella in primo luogo, ma penso che tu abbia l'idea. Mi piacerebbe avere un modo di dire, in effetti,
" Questa affermazione non altererà in alcun modo i dati esistenti {...} "
.
Il modo in cui è codificato in questo momento è fare la concatenazione di stringhe come nella risposta di friol , ma questo non comporta alcuna sanificazione. Mi sentirei meglio se potessi almeno scrub per personaggi sospetti, tipo; o - o cosa hai. Speravo che ci potesse essere una funzione di libreria per fare lo scrub per me, o qualcosa del genere.
Soluzione
Forse non l'ho capito bene, ma cosa ti impedisce di fare:
viewname="foo";
viewwhere="* from bar";
SqlCommand cmd = new SqlCommand("CREATE VIEW "+viewname+" AS SELECT "+viewwhere);
Altri suggerimenti
I parametri non sono semplicemente sostituzioni di stringhe. Ecco perché il tuo codice non funzionerà.
È come non si può fare
sql = " select * dagli ordini in cui ordini_del (?) "
e passa "1,2,3,5" come parametro.
I parametri sono controllati dal tipo e possono contenere solo valori scalari IIRC.
Iniezione SQL. Lo vuoi, questo è il punto. Dovresti concatenare queste cose.
Mi sembra che tu stia cercando di creare una query dinamica utilizzando parametri, il che non è il modo in cui una query con parametri è destinata a funzionare. Non si concatenano semplicemente nella stringa.
Se ciò che si sta tentando di prevenire è l'iniezione SQL, ciò che farei è convalidare che il nome della vista contiene solo caratteri alfanumerici e nessuna parola chiave T-SQL. Starei molto attento anche a creare il corpo dymanically.