2011-12-01 15 views
5

Estoy empezando a trabajar con ASP.NET C# y mi base de datos es SQL Server. Estoy tratando de escribir una consulta en la que quiero usar una declaración preparada.Declaración preparada en ASP.Net C# cuando se usa SQL Server

Esta es una consulta que permite registro de usuario para:

SqlParameter UserName = new SqlParameter("@user", SqlDbType.NVarChar, 30); 
    SqlParameter Password = new SqlParameter("@pass", SqlDbType.NVarChar, 20); 

    UserName.Value = user.ToLower(); 
    Password.Value = pass; 

    SqlCommand command = new SqlCommand(null, conn); 
    command.Parameters.Add(UserName); 
    command.Parameters.Add(Password); 
    command.CommandText = "SELECT * FROM table_users WHERE user_name = '@user' AND password = '@pass';"; 

    command.Prepare(); 
    SqlDataReader reader = command.ExecuteReader(); 

    bool tmp = reader.HasRows; 

tmp valor de la variable siempre FALSE, incluso cuando entro existir usuario con la contraseña correcta.

Si acabo de quitar parámetros y escribir la consulta de esta manera:

command.CommandText = "SELECT * FROM table_users WHERE user_name = '"+user+"' AND password = '"+ pass+"';"; 

tmp valor de obtener la variable de TRUE existe usuarios.

He intentado utilizar esta sintaxis para las consultas INSERT INTO y funciona correctamente.

Ya leí todas las sugerencias sobre cómo cambiar @ a ? y no funciona. que ha habido un error:

Incorrect syntax near '?'. Statement(s) could not be prepared.

Ayúdame por favor, Gracias!

Respuesta

9

Está buscando literales'@user' y '@pass', en lugar del valor del parámetro; uso:

command.CommandText = 
     "SELECT * FROM table_users WHERE user_name = @user AND password = @pass;"; 

en su lugar. Luego busque "hashes salados", y por qué nunca debería almacenar contraseñas.

Por cierto, llamar al Prepare() aquí no está ayudando aquí. También voy a tapar pulcro-punto-net (gratis/OSS), lo que haría que toda esta cosa simplemente:

bool authenticated = conn.Query(
    @"select 1 from table_users where user_name = @user and password = @pass", 
    new {user = user.ToLower(), pass}).Any(); 

o, si desea que el registro:

var tableUser = conn.Query<TableUser>(
    @"select * from table_users where user_name = @user and password = @pass", 
    new {user = user.ToLower(), pass}).SingleOrDefault(); 
+0

Muchas gracias mucho, ahora es su trabajo. Verificaré los "hashes salados". –

+0

@MarkGravell - "Por cierto, llamar a Prepare() aquí no está ayudando aquí". ¿Podrían dar más detalles sobre "por qué" usar una declaración preparada no ayuda en este uso? –

+2

@Jesse porque la mayoría de las bases de datos en estos días no se preocupan: tienen un caché de plan de consultas automático en consultas ad-hoc que hace cualquier diferencia básicamente indestructible –

Cuestiones relacionadas