2008-11-03 9 views
0

J'ai une base de données (SQL Server 2005) où je voudrais créer des vues à la volée. Dans mon code, je construis une instruction CREATE VIEW, mais la seule façon de le faire fonctionner est de construire la chaîne de requête entière et de l'exécuter à vide. Je voudrais utiliser des paramètres, mais ceci:Paramètre CREATE VIEW possible?

SqlCommand cmd = new SqlCommand("CREATE VIEW @name AS SELECT @body"); 
cmd.Parameters.AddWithValue("@name", "foo"); 
cmd.Parameters.AddWithValue("@body", "* from bar"); 

me dit qu'il ya une erreur « à proximité du mot-clé VIEW » (probablement le « @name ») - inutile de dire "CREATE VIEW foo AS SELECT * FROM bar" fonctionne comme un champion.

Est-ce que ce n'est pas possible? Sinon, existe-t-il un meilleur moyen de nettoyer l'entrée avant d'exécuter l'instruction CREATE? Dans certains cas, le corps de la requête pourrait avoir une entrée de l'utilisateur et je me sentirais plus en sécurité s'il y avait un moyen de dire «traiter cela comme le corps d'une seule instruction select». Peut-être que ce que je demande est trop bizarre?


FOLLOWUP 4 novembre: OK, oui, ce que je veux est un peu comme l'injection SQL lorsque vous descendez à elle, mais je voudrais au moins minimiser (voire supprimer totalement) la possibilité d'exécuter cette commander et déposer une table ou quelque chose. Certes, l'utilisateur est en cours d'exécution car il n'a pas les autorisations pour déposer des tables en premier lieu, mais je pense que vous avez l'idée. J'aimerais avoir une façon de dire, en effet, "This statement will not alter any existing data in any way{ ... }".

La façon dont il est codé en ce moment est de faire la concaténation de chaîne comme dans la réponse de friol, mais cela ne fait aucune aseptisation du tout. Je me sentirais mieux si je pouvais au moins le frotter pour des caractères suspects, comme; ou - ou qu'est-ce que vous avez. J'espérais qu'il pourrait y avoir une fonction de bibliothèque pour faire le gommage pour moi, ou quelque chose du genre.

Répondre

1

Peut-être que je ne l'ai pas compris correctement, mais ce que vous empêche de le faire:

viewname="foo"; 
viewwhere="* from bar"; 

SqlCommand cmd = new SqlCommand("CREATE VIEW "+viewname+" AS SELECT "+viewwhere); 
+0

Est-ce sécuritaire? Est-ce que cela empêche l'injection SQL? –

+1

Eh bien, vous donnez à l'utilisateur la possibilité d'écrire n'importe quelle requête. C'est la * définition * de l'injection SQL :) –

4

Les paramètres ne sont pas simplement des substitutions de chaîne. C'est pourquoi votre code ne fonctionnera pas.

est comme vous ne pouvez pas faire

sql = "select * from orders where orders_id en (?)"

et passer "1,2,3,5" comme paramètre.

Les paramètres sont vérifiés par type et ne peuvent contenir que des valeurs scalaires IIRC.

0

Il me semble que vous essayez de créer une requête dynamique à l'aide de paramètres, ce qui n'est pas le but d'une requête paramétrée. Ils ne sont pas simplement concaténés dans la chaîne. Si ce que vous essayez d'empêcher est l'injection SQL, ce que je voudrais faire est de valider que le nom de la vue ne contient que des alphanumériques et pas de mots-clés T-SQL. Je serais aussi très prudent sur la création dymanically le corps.

1

Injection SQL. Vous le voulez, c'est le point. Vous devriez concaténer ce genre de choses.