Question

I've been trying to perform a login query. I think my main problem with this function is the Parameters.AddWithValue portion, but don't really understand what is wrong.

Following code returns an error when ran:

Must declare the table variable "@database"

Code:

 public static bool clsFuncLogin(string USER, string PASS, 
         string conStr, string strDatabase)
{
    SqlConnection conn = new SqlConnection(
       ConfigurationManager.ConnectionStrings[conStr].ConnectionString);
    conn.Open();


    using (SqlCommand StrQuer = 
         new SqlCommand("SELECT COUNT(*) FROM @database "+ 
            "WHERE Username = @userid AND Password = @password", conn))
    {
        StrQuer.Parameters.AddWithValue("@userid", USER);
        StrQuer.Parameters.AddWithValue("@password", PASS);
        StrQuer.Parameters.AddWithValue("@database", strDatabase);
        int DataQuery = Convert.ToInt32(StrQuer.ExecuteScalar().ToString());
        if (DataQuery == 1)
        {
            System.Web.HttpContext.Current.Session["User"] = USER;
            System.Web.HttpContext.Current.Session["Pass"] = PASS;
            System.Web.HttpContext.Current.Session["loggedIn"] = "True";

            return true;

        }
        else if (DataQuery > 1)
        {
           //to tell if a double is created in the db
           //probably to be removed

            System.Web.HttpContext.Current.Session["Double"] = USER;
            return false;
        }
        else 
        {
            return false;

        }
    }
}

Ive also done the query as

"SELECT COUNT(*) FROM" + strDatabase + " WHERE Username = " + USER + 
        " AND Password = " + PASS;

but I was told that that is bad practice. Any advice?

Was it helpful?

Solution

I've never seen table names passed as a parameter, and based on other posts (this and this for example), I don't think it can be easily done... at least, not via SqlCommand.Parameters.

It sounds like there's only two tables - admins and regular users. As an alternative, you could just pass a bool to the method, like isAdmin, then have two queries based on whether the user is an admin or a regular user.

public static bool clsFuncLogin(string user, string pass, string conStr, bool isAdmin)
{
    ...

    var query = isAdmin
        ? "SELECT COUNT(*) FROM ADMIN_TABLE WHERE Username = @userid AND Password = @password"
        : "SELECT COUNT(*) FROM REGULAR_TABLE WHERE Username = @userid AND Password = @password";

    using (var sqlCommand = new SqlCommand(query, conn))
    {
        sqlCommand.Parameters.AddWithValue("@userid", user);
        sqlCommand.Parameters.AddWithValue("@password", pass);

        ...
        ...

OTHER TIPS

Main reason to use

SELECT * FROM TABLE WHERE column=@column

with parameters is to avoid all complications of providing correct formatting for the value. it is even more important if values are supplied as free text by user of your application since you will open all possibilities with SQL injection attacks if you fail to properly address all formatting issues (which is basically not worth the effort given solution with parameters).

I really hope that you don't allow users to supply table name and it's supplied by your own code, so you can quite safely use

var query = String.Format("SELECT * FROM {0} WHERE column=@column", tableName);

However I would just recommend to create two separate queries instead to properly separate concerns.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top