2010-07-25 14 views
5

¿Hay alguna forma de hacerlo? Esto no funciona:C# SqlCommand: no se pueden usar parámetros para los nombres de columnas, ¿cómo resolverlos?

SqlCommand command = new SqlCommand("SELECT @slot FROM Users WHERE [email protected]; "); 
prikaz.Parameters.AddWithValue("name", name); 
prikaz.Parameters.AddWithValue("slot", slot); 

Lo único que se me ocurre es el uso de SP y declarar y establecer la variable de la columna. Me parece un poco incómodo.

+0

considera que su '' de los usuarios mesa se deshace la normalización, por lo tanto, la La solución a su problema implicaría resolver el diseño a la quinta forma normal. – onedaywhen

Respuesta

4

No puede hacer esto en SQL normal; si debe tener nombres de columna configurables (o nombre de tabla, para el caso), debe usar SQL dinámico: no hay otra manera de lograr esto.

string sqlCommandStatement = 
    string.Format("SELECT {0} FROM dbo.Users WHERE [email protected]", "slot"); 

y luego usar el sp_executesql procedimiento almacenado en SQL Server para ejecutar ese comando SQL (y especifique los otros parámetros según sea necesario).

SQL dinámico tiene sus pros y sus contras - lea el último artículo en The Curse and Blessings of Dynamic SQL escrito expertamente por el MVP de SQL Server, Erland Sommarskog.

+1

El código de ejemplo que se da arriba no muestra SQL dinámico, simplemente muestra el uso de la función string.Format. Como está escrito, es confuso. – Yellowfog

+0

@Yellowfog: ahora toma esta cadena que ha sido formateada y úsala en una llamada a "sp_executesql" y tienes tu SQL dinámico ..... –

+0

Bueno, tienes tu SQL, pero no es particularmente 'dinámico', es mi punto. Según entiendo esto, se refiere a SQL que se construye en el lado de la base de datos, no en el lado del servidor web. ¿O soy inusual en tomar el término de esa manera? – Yellowfog

7

Como se ha mencionado, no se puede parametrizar la consulta fundamental, por lo que deberá compilar la consulta en tiempo de ejecución. Usted debe lista blanca la entrada de este, para evitar ataques de inyección, pero fundamentalmente:

// TODO: verify that "slot" is an approved/expected value 
SqlCommand command = new SqlCommand("SELECT [" + slot + 
      "] FROM Users WHERE [email protected]; ") 
prikaz.Parameters.AddWithValue("name", name); 

De esta manera @name todavía está parametrizado etc.

Cuestiones relacionadas