This question already has answers here:
add selected value to users profile
(2 answers)
Closed 9 years ago.
I am trying to write an insert statement where the job is to take selected item the user has selected then insert it into their profile.
I am using Profile provider.
There is a new column I have made in UserProfile table (that stores stuff like username, age and so forth) and I have called it Rented.
e.g.:
User Tom45
rented Pirates of The caribbean
age 23
Could someone let me know if I am doing it right as I can't seem to get it to work.
My Insert and SQL:
protected void Button3_Click(object sender, EventArgs e)
{
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\ASPNetDB.mdb;Persist Security Info=True");
{
da.InsertCommand = new OleDbCommand("INSERT INTO UserProfile (Rented) VALUES (#Rented) WHERE [UserName] = ?", conn);
string dvdrent = DG_Latest.SelectedRow.Cells[1].Text;
OleDbParameter rented = new OleDbParameter();
{
da.InsertCommand.Parameters.AddWithValue("#Rented", DG_Latest.SelectedRow.Cells[2].Text);
}
conn.Open();
da.InsertCommand.ExecuteNonQuery();
conn.Close();
conn.Dispose();
}
}
I have this table:
And each user has a profile:
Once they're logged in they can choose to rent dvds:
The problem is I do not think my query does this, as it does not work.
instead #Render write question mark.
you need add second parameter for the User criteria, and set it.
so:
protected void Button3_Click(object sender, EventArgs e)
{
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\ASPNetDB.mdb;Persist Security Info=True");
{
da.InsertCommand = new OleDbCommand("INSERT INTO UserProfile (Rented) VALUES (?) WHERE [UserName] = ? ;", conn);
da.InsertCommand.Parameters.AddWithValue("#Rented", DG_Latest.SelectedRow.Cells[2].Text);
da.InsertCommand.Parameters.AddWithValue("#User", XXXXXXXXX);
conn.Open();
da.InsertCommand.ExecuteNonQuery();
conn.Close();
conn.Dispose();
}
}
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement or a stored procedure called by an OleDbCommand when CommandType is set to Text. In this case, the question mark (?) placeholder must be used.
source: msdn
Related
I am trying to make a user register page that uploads the user data to a sql server database. I want to have the capability to check if a username already exists and prevent it from being made. I am able to create a new user with first name, last name, username, etc and it updates the database, but it doesn't stop me from creating a user with a username that already exists in the database. Here is my code:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
//connect registration form to database
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["sandboxConnectionStringUserData"].ConnectionString);
conn.Open(); //open connection
//SQL Query
string checkUserName = "select count(*) from UserData where UserName='"+TextBoxUserName.Text+"'";//checks if username is already there
SqlCommand command = new SqlCommand(checkUserName, conn);
int temp = Convert.ToInt32(command.ExecuteScalar().ToString());
if(temp == 1)
{
Response.Write("User name already exists");
}
conn.Close(); //close the database
}
}
I tried debugging and temp's value never changes to 1.
Thanks!
Just add a UNIQUE constraint to the username column and handle the sql exception in your app. Additionally you can/should write an SP that takes username as an argument and checks for existence in the table, and use that in your server-side validation after the form is sorted but before the insert (save()) occurs. That way you reduce the probability of encountering a sql exception but can still deal with it if it occurs.
Your current method of appending the form data to a raw sql query is going to open you up to sql injection. Use a parameterized query instead.
Creating a UNIQUE constraint on the UserName column is a good start. I would also create a stored procedure that checks the existence of the user and inserts or updates as well structure your code a bit more efficiently. The username should be passed in as a parameter and you should properly dispose of the connection object.
As an example your stored procedure may look like:
CREATE PROCEDURE dbo.uspUserData #userName VARCHAR(50)
AS
BEGIN
IF EXISTS(SELECT 1 FROM dbo.UserData WITH(NOLOCK)
WHERE UserName = #userName)
BEGIN
-- update
END
ELSE
BEGIN
-- insert
END
END
And your .NET code may look like:
using (
SqlConnection conn =
new SqlConnection(
ConfigurationManager.ConnectionStrings["sandboxConnectionStringUserData"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("uspUserData", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#UserName", SqlDbType.VarChar).Value = TextBoxUserName.Text;
conn.Open();
cmd.ExecuteNonQuery();
}
}
I am having an issue with the increment for the ID. The ID would increase by one every time I click insert, but the problem occurs when the ID 2, it would insert the values twice, if ID 3, it would insert the values three times, and so on.
There are couple of options that I have been trying. One is Max and the other one is finding the last inserted value and add one to the ID just.
I would appreciate if anyone can help me out with this. Thanks
public partial class LoginInfo : System.Web.UI.Page
{
static string myConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
private void GenerateID()
{
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myQuery1 = "Select Count(S_ID) from Student_Name";
SqlCommand cmd = new SqlCommand(myQuery1, myConnection);
myConnection.Open();
int addOneS_ID_Table1 = Convert.ToInt32(cmd.ExecuteScalar());
myConnection.Close();
addOneS_ID_Table1++;
lblstdID.Text = addOneS_ID_Table1.ToString();
myConnection.Open();
cmd.CommandText = "Select Count(P_ID) from Student_Pass";
int addOneP_ID_Table2 = Convert.ToInt32(cmd.ExecuteScalar());
myConnection.Close();
addOneP_ID_Table2++;
lblstdPass.Text = addOneP_ID_Table2.ToString();
/*-----------------------------------------------------------------*/
//SqlConnection myConnection = new SqlConnection(myConnectionString);
//SqlCommand cmd = new SqlCommand("SELECT MAX(S_ID) as max_S_ID from Student_Name",myConnection);
//cmd.CommandType = CommandType.Text;
//myConnection.Open();
//lblstdID.Text = Convert.ToString(cmd.ExecuteScalar());
//cmd.CommandText = "SELECT MAX(P_ID) as max_P_ID FROM Student_Pass";
//lblstdPass.Text = Convert.ToString(cmd.ExecuteScalar());
//myConnection.Close();
}
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
GenerateID();
}
}
protected void btnInsert_Click(object sender, EventArgs e)
{
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myQuery = "Insert into Student_Name(S_ID,STUDENT_NAME) VALUES" + "(#S_ID,#STUDENT_NAME)";
SqlCommand cmd = new SqlCommand(myQuery,myConnection);
cmd.Parameters.Add("#S_ID", SqlDbType.Int).Value = lblstdID.Text;
cmd.Parameters.Add("#STUDENT_NAME", SqlDbType.VarChar).Value = txtstdName.Text;
if(myConnection.State == ConnectionState.Closed)
{
myConnection.Open();
}
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
//Second Table
cmd.CommandText = "Insert into Student_Pass(P_ID,PASSWORD) VALUES" + "(#P_ID,#PASSWORD)";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#P_ID", SqlDbType.Int).Value = lblstdPass.Text;
cmd.Parameters.Add("#PASSWORD", SqlDbType.VarChar).Value = txtStdPass.Text;
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
myConnection.Close();
GenerateID();
lblResult.Text = "Successfully Saved";
GridView1.DataBind();
}
}
Problem is with your query since you are getting COUNT(S_ID) which is going to get you count of records doesn't necessarily will give exact ID number. You should rather try MAX(S_ID) or ORDER BY clause saying
Select MAX(S_ID) from Student_Name
(OR)
Select TOP 1 S_ID from Student_Name ORDER BY S_ID DESC;
But recommended, You should actually go with SQL Server ##IDENTITY or SCOPE_IDENTITY() to get the last inserted record ID (assuming that S_ID is an IDENTITY column)
It's highly recommended to not use max or top in order to determine the "next" identifier to use, simply because of the cost associated with it.
However, there are some other pitfalls to using max and top especially if there is a chance that nolock is used (which is a whole other conversation). I've seen a lot of web applications use max and has proven to be a performance killer.
Rahul is right, ##identity or scope_identity are good alternatives. However, I think this calls for using a native SQL Server sequence, which was introduced in SQL Server 2012. It was something that application developers have been waiting for and Microsoft finally delivered.
The issue with using ##identity or scope_identity is that you actually have to write rows to some table before you can even contemplate doing something.
This makes it a bit more costly and messier than what it may need to be. In the case of using a sequence, you can issue a new sequence number and then decide what to do and once you decide what to do you're still guaranteed that you're the only one with that sequence number.
You would create a sequence like this. You should check out the documentation as well.
create sequence dbo.StudentIdSeq
as int -- this can be any integer type
start with 1 -- you can start with any valid number in the int, even negative
increment by 1;
go
Then you issue new sequence numbers by doing this ...
select next value for StudentIdSeq;
It may still be good to create a stored procedure with an output parameter that you can call from C# (which is what I would do). In fact you may want to take it a step further, in the case that you have a bunch of sequences, and create a slick stored procedure that will get a new sequence based on the type that is being requested from the caller.
This question already has answers here:
SqlCommand INSERT INTO query does not execute
(3 answers)
Closed 7 years ago.
I am using visual studio, i have a connection to an SQL server and im trying to update a table in the database.
I am not recieving any errors nor am i updating anything
Below is the code i have used
protected void Btn1_Click(object sender, EventArgs e)
{
//SQL for insert here.
string MyConnectionString = ConfigurationManager.ConnectionStrings
["testconnect"].ConnectionString;
SqlConnection myConnection = new SqlConnection();
myConnection.ConnectionString = MyConnectionString;
myConnection.Open();
SqlCommand cmd = new SqlCommand("insert into Don_Test (ID, Test) values ('" + IDTxt.Text + "','" + TESTTxt.Text + "')", myConnection);
//Call refresh
refreshPage();
myConnection.Close();
}
Actually, you are not executing your query, but just opening connection and closing it later.
Add line of code cmd.ExecuteNonQuery(); before refreshPage().
Also notice - concatenating query text is very bad idea since it leads to SQL injection attack.
Use parameterized query instead.
I am trying to update my database(Table) and make the active column = 1.
I have duplicate reports (subject_text) with different countries and parameters.
subject_text countries parameter1 active
usage GB 1 0
usage FR 2 0
usage PT 1 0
closed GB,FR,PT 1 0
Here is an example of what my database looks like(simplified, there are many more parameters and many more reports but i hope you can see what I mean by duplicate report names)
Here is my .cs file to show the update i am trying to carry out.The Subject_text are in drop-down list form so the user can select which report to update. These reports(subject_text) are hard-coded into my ASPX page. When selecting a report such as 'closed' the update works, but when it comes to updating reports which have different countries or parameters that where i'm having trouble.
Masterpage masteris linking this page to where the .getDropDownListValue is
How can I add to my update statement when the drop-down lists contain different elements?
protected void RunReport_Click (object sender, System.EventArgs e)
{
MasterPage master = (MasterPage)this.Master;
string sqlStatement = "";
sqlStatement = #"UPDATE [TODD].[dbo].[Table] SET Active='1' WHERE subject_text = #report";
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(sqlStatement, conn);
cmd = new SqlCommand(sqlStatement, conn);
cmd.Parameters.AddWithValue("#report", ddl_Report.SelectedItem.Text);
string getcountry = master.getDropDownListValue(ddl_country, false);
if (!string.IsNullOrWhiteSpace(getcountry))
{
cmd.Parameters.AddWithValue("#country", getcountry);
sqlStatement += "AND countries = #country";
}
string getparam1 = master.getDropDownListValue(Param1, false);
if (!string.IsNullOrWhiteSpace(getparam1))
{
cmd.Parameters.AddWithValue("#param1", getparam1);
sqlStatement += "AND parameter1 = #param1";
}
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
Thank you for your time.
move
SqlCommand cmd = new SqlCommand(sqlStatement, conn);
to below the final calculation of your string sqlStatement
adding new text to sqlStatement should be done before you create your SqlCommand based on sqlStatement
also, you do not need to call new SqlCommand(sqlStatement, conn); twice
Why don't you just pass the identity? This is much cleaner.
UPDATE [TODD].[dbo].[Table] SET Active='1' WHERE RecordID = #RecordId
Setting aside the salt and hash debate. And Please reply only if you know the answer.
I am trying to create a method where a user enters their credentials with date and times are recorded automatically when logging in and out.
I have two problems
Problem 1 -
I have created a simple method just for logging in and out. When I included the date and time code I noted that these where recorded and stored for all users. I currently have two users. So if one user logins date and time are recorded and stamp for the other user.
Problem 2 -
The second problem is as the subject headers says I get a error message when the Update command parameter is in the same method as with Select.
If anyone could help me I would be grateful with both of the problems. Hopefully It is only a minor issue? If omitting date and time then I will be grateful if someone could help me on multi login function.
Access 2003 ~ Two tables. Table 1 - Named LoginTable Table 2 - Named LoginLogTable
LoginTable
FieldName DataType
UserName Text
Password Text
LoginLogTable
FieldName DataType
UserNameID Text
UserName Text
LoggedIn Date/Time
LoggedInTime Date/Time
private void btnLogin_Click(object sender, EventArgs e)
{
using (var command = myCon.CreateCommand())
{
command.CommandText = "select UserName, Password from LoginTable where WHERE STRCOMP(UserName, #UserName,0) = 0 AND STRCOMP(Password, #Password,0)=0";
command.Parameters.AddWithValue("UserName", (txtUserName.Text));
command.Parameters.AddWithValue("Password", (txtPassword.Text));
myCon.Open();
var reader = command.ExecuteReader();
{
if (reader.HasRows)
{
MessageBox.Show("Login Successful");
Form2 frm = new Form2();
frm.Show();
while (reader.Read())
{
txtUserName.Text = reader["UserName"].ToString();
txtPassword.Text = reader["Password"].ToString();
}
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = myCon;
cmd.CommandText = "UPDATE [LoginLogTable] SET [LoggedInDate] = ?, [LoggedInTime] = ?";
cmd.Parameters.AddWithValue("#LoggedInDate", DateTime.Now.ToShortDateString());
cmd.Parameters.AddWithValue("#LoggedInTime", DateTime.Now.ToString("HH:mm"));
cmd.ExecuteNonQuery();
myCon.Close();
}
else MessageBox.Show("Login Falied");
}
}
myCon.Close();
myCon.Close();
}
You don't have any condition in your update query, so it will update all records in the table. Add a condition to only update a single record. I don't know what you have in your table, but something like this:
cmd.CommandText = "UPDATE [LoginLogTable] SET [LoggedInDate] = ?, [LoggedInTime] = ? where UserName = ?";
cmd.Parameters.AddWithValue("LoggedInDate", DateTime.Now.ToShortDateString());
cmd.Parameters.AddWithValue("LoggedInTime", DateTime.Now.ToString("HH:mm"));
cmd.Parameters.AddWithValue("UserName", txtUserName.Text);
You should close and dispose the first data reader and command before executing the second command.
I suppose you need a UserName column in your LoginLogTable and update table something like this
UPDATE [LoginLogTable] SET [LoggedInDate] = ?, [LoggedInTime] = ? WHERE UserName = 'YourUserName'.
And the second, I believe you no need a Reader here. You can use ExecuteScalar instead Reader. The second command can not run because a Reader has open state.